Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow on-* attribute to bind additional arguments #401

Closed
mlrawlings opened this issue Nov 6, 2016 · 2 comments
Closed

Allow on-* attribute to bind additional arguments #401

mlrawlings opened this issue Nov 6, 2016 · 2 comments
Assignees
Milestone

Comments

@mlrawlings
Copy link
Member

As mentioned in #394, we are moving from w-on-click="method" to on-click('method') as the way to delegate events within a template.

We also want to allow you to bind additional arguments:

<ul for(color in colors)>
    <li onClick('colorClick', color)>${color}</li>
</ul>

Bound arguments will be prepended to the argument list much like a function bind in js:

colorClick(color, event) {
    console.log(color, 'was clicked');
}
@patrick-steele-idem
Copy link
Contributor

As an implementation detail, we want to avoid serializing the extra arguments to a JSON stringify in the browser. On the server we have no choice but to JSON.stringify() each argument and store it in the DOM. However, in the browser we can store the extra arguments as part of the virtual DOM attribute map that is associated with the real DOM node.

@patrick-steele-idem
Copy link
Contributor

patrick-steele-idem commented Nov 14, 2016

I've been giving this issue some more thought and am capturing some of my thoughts/notes below for discussion:

Currently, marko associates a DOM event with a handler method on a particular widget by rendering out a special data-w-on attribute in the following format:

<div data-w-onevent="method_name|widget_id">

For example:

<div data-w-onclick="handleButtonClick|w0-myButton|<arg1">

Now, with this change need to associate additional arguments with the event handler. For example:

<div data-w-onclick="handleButtonClick|w0-myButton|arg1|arg2|arg3">

What I am thinking is that in v4 we can make some changes to support providing a complex object with an attribute. For example:

<div data-w-onclick={method: 'handleButtonClick', widgetId: 'w0', args: [ 'foo', 'bar' ] }>

Currently, this renders as the following since we call toString() on the object:

<div data-w-onclick="[object Object]"></div>

We could choose to JSON.stringify() attribute values that are objects to produce:

<div data-w-onclick='{"method":"handleButtonClick","widgetId":"w0","args":["foo","bar"]}'>

If rendered in the browser, there is likely no reason to JSON.stringify() the attribute value unless we want it to be part of the DOM as an HTML attribute. Instead, we could keep the complex attribute value as a property of the VDOM attributes, but not actually make it an actual HTML attribute on the DOM. This might give us a nice way to keep extra info with an HTML element, but the user of this "extra info" would need to know about how to get access to the data using some internal API. For example:

var eventInfo = require('marko').getObjectAttribute(el, 'data-w-onclick');
console.log(eventInfo.method);

That's all for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants