Change syntax for passing in template objects to Components to use `{}` #814

Closed
zkat opened this Issue Mar 21, 2014 · 36 comments

Comments

Projects
None yet
9 participants
@zkat
Contributor

zkat commented Mar 21, 2014

Right now, passing an object argument to a can.Component involves putting a plain string in an attribute, like so:

<can-didgeridoo state="state"></can-didgeridoo>

With the template rendered like:

can.view("#mytemplate", {state: {foo: 1, bar: 2}});

Note that, in this case, the "state" string will be interpreted differently by the can.Component depending on whether you set the default value to state: "@", in its scope.

I propose the following alternative for passing mustache context values into can.Component:

<can-didgeridoo state="{{state}}" name="name"></can-didgeridoo>

Where "{{state}}" will automatically look that value up and pass it into the component, and "name" will pass the string directly into the component.

I believe this is clearer, and will also remove the need to use "@" to configure whether we should interpret it as a string or look it up.

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Mar 21, 2014

Contributor

It will mean different processing rules for {{}} within a custom element vs everywhere else. Those {{}} would have to be ignored for later.

Considering can-value / can-EVENT, would they look like:

<input can-value="{{item}}"/>
<button can-click="{{destroy}}">

Removing looking up state in state="state" would be a breaking change ... unless it was done in stache ....

Contributor

justinbmeyer commented Mar 21, 2014

It will mean different processing rules for {{}} within a custom element vs everywhere else. Those {{}} would have to be ignored for later.

Considering can-value / can-EVENT, would they look like:

<input can-value="{{item}}"/>
<button can-click="{{destroy}}">

Removing looking up state in state="state" would be a breaking change ... unless it was done in stache ....

@moschel

This comment has been minimized.

Show comment
Hide comment
@moschel

moschel Mar 21, 2014

Contributor

I agree that this is hard to understand and initially when reading the component implementation took a few readthroughs for me to pick up on. There's 2 cases, passing a string in the attribute, and mapping a scope property from the parent scope.

I agree with Josh in the sense that the @ syntax is what people would expect the normal case to be, not the exception. And the case where we're passing data, we pass data everywhere else via {{ }}.

Stan proposed an alternate solution that removes the need for @, which is using a special attribute, like scope-myProp="selection". I still think I like Josh's first proposal better.

Contributor

moschel commented Mar 21, 2014

I agree that this is hard to understand and initially when reading the component implementation took a few readthroughs for me to pick up on. There's 2 cases, passing a string in the attribute, and mapping a scope property from the parent scope.

I agree with Josh in the sense that the @ syntax is what people would expect the normal case to be, not the exception. And the case where we're passing data, we pass data everywhere else via {{ }}.

Stan proposed an alternate solution that removes the need for @, which is using a special attribute, like scope-myProp="selection". I still think I like Josh's first proposal better.

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Mar 21, 2014

Contributor

Part of the issue ... I'm trying to transition away from mustache and {{}} in general to favor more of an html-only API.

Contributor

justinbmeyer commented Mar 21, 2014

Part of the issue ... I'm trying to transition away from mustache and {{}} in general to favor more of an html-only API.

@moschel

This comment has been minimized.

Show comment
Hide comment
@moschel

moschel Mar 21, 2014

Contributor

agree that its a breaking change, but would go well with the other breaking changes in 2.1. Its something thats "hard to explain" and this proposal will simplify. I think its worth it, even if its only in can.stash

Contributor

moschel commented Mar 21, 2014

agree that its a breaking change, but would go well with the other breaking changes in 2.1. Its something thats "hard to explain" and this proposal will simplify. I think its worth it, even if its only in can.stash

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Mar 21, 2014

Contributor

Although one could argue that looking up a value in a "scope" is inherently non-HTML ish ... it still feels great.

@moschel There are no breaking changes in 2.1. It's a minor release. It would have to wait until 3.0 if its in mustache.

Contributor

justinbmeyer commented Mar 21, 2014

Although one could argue that looking up a value in a "scope" is inherently non-HTML ish ... it still feels great.

@moschel There are no breaking changes in 2.1. It's a minor release. It would have to wait until 3.0 if its in mustache.

@moschel

This comment has been minimized.

Show comment
Hide comment
@moschel

moschel Mar 21, 2014

Contributor

I think it adds some consistency by requiring all usage of scope properties to be wrapped in {{}}.

For example, what's the difference between class="{{foo}}" and can-value="{{foo}}" from a user's perspective. They both bind a property of scope, but right now, they are written differently. That difference is hard to explain/remember IMO

Contributor

moschel commented Mar 21, 2014

I think it adds some consistency by requiring all usage of scope properties to be wrapped in {{}}.

For example, what's the difference between class="{{foo}}" and can-value="{{foo}}" from a user's perspective. They both bind a property of scope, but right now, they are written differently. That difference is hard to explain/remember IMO

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Mar 21, 2014

Contributor

@moschel Still, I find there will be a lot of weirdness with can-value and can-EVENT unless we also change their APIs.

And, it will be strange if in can.stache, calling components looks different. It will slow adoption for can.stache.

Contributor

justinbmeyer commented Mar 21, 2014

@moschel Still, I find there will be a lot of weirdness with can-value and can-EVENT unless we also change their APIs.

And, it will be strange if in can.stache, calling components looks different. It will slow adoption for can.stache.

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Mar 21, 2014

Contributor

I agree there's a problem. I'm not sure adding more {{}} is the ultimate solution. We should at least check out how more html-centric view layers solve this problem.

Contributor

justinbmeyer commented Mar 21, 2014

I agree there's a problem. I'm not sure adding more {{}} is the ultimate solution. We should at least check out how more html-centric view layers solve this problem.

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Mar 21, 2014

Contributor

Currently, if you write can-value="{{prop}}", it offers some additional flexibility. For instance, I could render this with:

{prop: "first", first: "Justin", last: "Meyer"}

And then changing prop to "last" would then change the cross-binding to operate on the last property.

I'm not claiming that this is a very useful feature. Just something to think about.

Contributor

justinbmeyer commented Mar 21, 2014

Currently, if you write can-value="{{prop}}", it offers some additional flexibility. For instance, I could render this with:

{prop: "first", first: "Justin", last: "Meyer"}

And then changing prop to "last" would then change the cross-binding to operate on the last property.

I'm not claiming that this is a very useful feature. Just something to think about.

@moschel

This comment has been minimized.

Show comment
Hide comment
@moschel

moschel Mar 21, 2014

Contributor

@justinbmeyer agree that changing the api for passing in scope to attributes would also require changing api for can-value and can-event. Doesn't make sense to just change one without the other being consistent.

Contributor

moschel commented Mar 21, 2014

@justinbmeyer agree that changing the api for passing in scope to attributes would also require changing api for can-value and can-event. Doesn't make sense to just change one without the other being consistent.

@shcarrico

This comment has been minimized.

Show comment
Hide comment
@shcarrico

shcarrico Mar 21, 2014

Contributor

how would this look when custom tags are placed directly in the page? ( not in a mustache template, script tag etc). Would it be confusing to see mustache syntax in your html?

Contributor

shcarrico commented Mar 21, 2014

how would this look when custom tags are placed directly in the page? ( not in a mustache template, script tag etc). Would it be confusing to see mustache syntax in your html?

@shcarrico

This comment has been minimized.

Show comment
Hide comment
@shcarrico

shcarrico Mar 21, 2014

Contributor

I am also curious why we need to use @ in the existing API.. couldn't we just pull the string value if the lookup failed?

Contributor

shcarrico commented Mar 21, 2014

I am also curious why we need to use @ in the existing API.. couldn't we just pull the string value if the lookup failed?

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Mar 21, 2014

Contributor

@shcarrico Yeah, this is what concerns me too. Doing something like:

$("<my-component/>").appendTo(document.body)

Is the thing I really want for 2.2. However, I'm not sure what we even do with "scope" in this situation. Do we walk up where we are inserting and look for elements that have been rendered with a scope?

Regarding:

I am also curious why we need to use @ in the existing API.. couldn't we just pull the string value if the lookup failed?

Not exactly .... it's possible someone want to do:

<parent-component>
  <child-component thing-id="thingId"></child-component>
</parent-component>

(I will fill this part in later ... have to get back to training)

Contributor

justinbmeyer commented Mar 21, 2014

@shcarrico Yeah, this is what concerns me too. Doing something like:

$("<my-component/>").appendTo(document.body)

Is the thing I really want for 2.2. However, I'm not sure what we even do with "scope" in this situation. Do we walk up where we are inserting and look for elements that have been rendered with a scope?

Regarding:

I am also curious why we need to use @ in the existing API.. couldn't we just pull the string value if the lookup failed?

Not exactly .... it's possible someone want to do:

<parent-component>
  <child-component thing-id="thingId"></child-component>
</parent-component>

(I will fill this part in later ... have to get back to training)

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Mar 21, 2014

Contributor

@sykopomp @moschel

Basically, just review how this is done in more HTML-based views. If they do not apply well to can.stache, you've got my support to make this change.

Please hurry up on that research though. I want to get out 2.1 pretty soon.

Contributor

justinbmeyer commented Mar 21, 2014

@sykopomp @moschel

Basically, just review how this is done in more HTML-based views. If they do not apply well to can.stache, you've got my support to make this change.

Please hurry up on that research though. I want to get out 2.1 pretty soon.

@moschel

This comment has been minimized.

Show comment
Hide comment
@moschel

moschel Mar 21, 2014

Contributor

ok, but didn't you just say this would be 3.0 only?

Contributor

moschel commented Mar 21, 2014

ok, but didn't you just say this would be 3.0 only?

@moschel

This comment has been minimized.

Show comment
Hide comment
@moschel

moschel Mar 21, 2014

Contributor

or you mean if we do it stash-only, then its ok for 2.1?

Contributor

moschel commented Mar 21, 2014

or you mean if we do it stash-only, then its ok for 2.1?

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Mar 21, 2014

Contributor

stash-only is ok for 2.1

Contributor

justinbmeyer commented Mar 21, 2014

stash-only is ok for 2.1

@daffl

This comment has been minimized.

Show comment
Hide comment
@daffl

daffl Mar 21, 2014

Contributor

It would break Mustache compatibility but since Stache is a new feature for 2.1 it would be ok. I personally like the syntax proposed by Josh because it removes a level of indirection while being more explicit.

The issue I'm still having with HTML based views is that templating logic needs to be thrown into the attributes (or special tags) somewhere. Angulars syntax is valid HTML but you have to do things that look like

<ul>
  <li ng-repeat="todo in todos | filter:statusFilter track by $index" ng-class="{completed: todo.completed, editing: todo == editedTodo}">...</li>
</ul>

vs

{{#each displayList}}
<ul>
  <li class="todo{{#if complete}} completed{{/if}}{{#if editing}} editing{{/if}}">...</li>
</ul>
{{/each}}

in CanJS. I know we are all biased but the Angular example isn't understandable with "just knowing HTML" at all (which I assume should be the ideal solution for HTML based views).

Contributor

daffl commented Mar 21, 2014

It would break Mustache compatibility but since Stache is a new feature for 2.1 it would be ok. I personally like the syntax proposed by Josh because it removes a level of indirection while being more explicit.

The issue I'm still having with HTML based views is that templating logic needs to be thrown into the attributes (or special tags) somewhere. Angulars syntax is valid HTML but you have to do things that look like

<ul>
  <li ng-repeat="todo in todos | filter:statusFilter track by $index" ng-class="{completed: todo.completed, editing: todo == editedTodo}">...</li>
</ul>

vs

{{#each displayList}}
<ul>
  <li class="todo{{#if complete}} completed{{/if}}{{#if editing}} editing{{/if}}">...</li>
</ul>
{{/each}}

in CanJS. I know we are all biased but the Angular example isn't understandable with "just knowing HTML" at all (which I assume should be the ideal solution for HTML based views).

@zkat

This comment has been minimized.

Show comment
Hide comment
@zkat

zkat Mar 21, 2014

Contributor

+1 for including this in can.stache. I think it'll feel better in practice, but it's great to have an opportunity to try it out without worrying about backwards compat.

I may have misunderstood what you said about html-only views, but -- I think the issue of wtf the context/viewscope is is orthogonal to this change. If we want custom elements to work standalone, we'll have to figure out an API for injecting scope data into the html page. Consider that, in Polymer, this {{foo}}-based insertion is only available for <template>, and its value depends entirely on where the template is used. You don't use {{}} for property values outside of this tag. At the toplevel, you do any context/scope population in whatever toplevel <my-app> wrapper you have, iiuc.

tl;dl: the issue of what attr="{{foo}}" means in the toplevel is orthogonal to this feature, unless I misunderstand web components.

Contributor

zkat commented Mar 21, 2014

+1 for including this in can.stache. I think it'll feel better in practice, but it's great to have an opportunity to try it out without worrying about backwards compat.

I may have misunderstood what you said about html-only views, but -- I think the issue of wtf the context/viewscope is is orthogonal to this change. If we want custom elements to work standalone, we'll have to figure out an API for injecting scope data into the html page. Consider that, in Polymer, this {{foo}}-based insertion is only available for <template>, and its value depends entirely on where the template is used. You don't use {{}} for property values outside of this tag. At the toplevel, you do any context/scope population in whatever toplevel <my-app> wrapper you have, iiuc.

tl;dl: the issue of what attr="{{foo}}" means in the toplevel is orthogonal to this feature, unless I misunderstand web components.

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Mar 23, 2014

Contributor

To attempt at being more clear:

If we are going towards templates without {{}}, I want to have better visibility into what they are going to look like without {{}} so that transition might be made more simply.

Contributor

justinbmeyer commented Mar 23, 2014

To attempt at being more clear:

If we are going towards templates without {{}}, I want to have better visibility into what they are going to look like without {{}} so that transition might be made more simply.

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Mar 30, 2014

Contributor

@sykopomp @moschel @daffl There's one hiccup with this ... can-EVENT. In the future, I want to support being able to call method with specified arguments like:

<div can-click="removeFrom(parent, child)"></div>

Where remove from might look like:

removeFrom = function(parent,child){
  parent.splice(parent.indexOf(child), 1)
}

This would mean changing it to look like:

<div can-click="{{removeFrom(parent, child)}}"></div>

Or even worse:

<div can-click="{{{{removeFrom}}({{parent}}, {{child}})}}"></div>

Thoughts?

In my opinion, this is so ugly, that I think we should still keep the existing behavior of can-EVENT.

Contributor

justinbmeyer commented Mar 30, 2014

@sykopomp @moschel @daffl There's one hiccup with this ... can-EVENT. In the future, I want to support being able to call method with specified arguments like:

<div can-click="removeFrom(parent, child)"></div>

Where remove from might look like:

removeFrom = function(parent,child){
  parent.splice(parent.indexOf(child), 1)
}

This would mean changing it to look like:

<div can-click="{{removeFrom(parent, child)}}"></div>

Or even worse:

<div can-click="{{{{removeFrom}}({{parent}}, {{child}})}}"></div>

Thoughts?

In my opinion, this is so ugly, that I think we should still keep the existing behavior of can-EVENT.

@daffl

This comment has been minimized.

Show comment
Hide comment
@daffl

daffl Mar 30, 2014

Contributor

It might be slightly harder to parse but why not call it like any other Handlebars helper?

<div can-click="{{removeFrom parent child}}"></div>
Contributor

daffl commented Mar 30, 2014

It might be slightly harder to parse but why not call it like any other Handlebars helper?

<div can-click="{{removeFrom parent child}}"></div>
@shcarrico

This comment has been minimized.

Show comment
Hide comment
@shcarrico

shcarrico Mar 30, 2014

Contributor

is it just me, or is this starting to look an awful lot like DHTML ? <a onclick="myFoo(bar,baz)>ugh</a> vs <a can-click="myFoo(bar,baz)>ugh</a>. Is this really where we are headed?

Contributor

shcarrico commented Mar 30, 2014

is it just me, or is this starting to look an awful lot like DHTML ? <a onclick="myFoo(bar,baz)>ugh</a> vs <a can-click="myFoo(bar,baz)>ugh</a>. Is this really where we are headed?

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Mar 30, 2014

Contributor

I'm not sure what you mean by DHTML. What you are showing is a DOM0 event handler.

Yes, this looks like DOM0, but works very differently. With mustache, myFoo, bar, and baz are all isolated to some scope. In DOM0, they are global variables, making DOM0 inherently difficult to maintain. This problem does not exist in mustache's scoped lookup.

CanJS has become MVVM. Enabling a powerful view is something we should work hard to accomplish. In-template declarative event binding like:

{{#each items}}
<a can-click="myFoo(bar,baz)">ugh</a>
{{/each items}}

Is far less code then the equivalent.

Contributor

justinbmeyer commented Mar 30, 2014

I'm not sure what you mean by DHTML. What you are showing is a DOM0 event handler.

Yes, this looks like DOM0, but works very differently. With mustache, myFoo, bar, and baz are all isolated to some scope. In DOM0, they are global variables, making DOM0 inherently difficult to maintain. This problem does not exist in mustache's scoped lookup.

CanJS has become MVVM. Enabling a powerful view is something we should work hard to accomplish. In-template declarative event binding like:

{{#each items}}
<a can-click="myFoo(bar,baz)">ugh</a>
{{/each items}}

Is far less code then the equivalent.

@shcarrico

This comment has been minimized.

Show comment
Hide comment
@shcarrico

shcarrico Mar 30, 2014

Contributor

Sorry for the fire off comment. It just strikes me that if this was injected in a page inline, it would appear much the same as a DOM0 attribute. It is perception in some cases that drives adoption so if this is the final syntax we should be prepared to offer the explanation you have given in the least case. It still looks a bit like inline JS to someone who spent years convincing people to stop doing that and learn "unobtrusive"

Contributor

shcarrico commented Mar 30, 2014

Sorry for the fire off comment. It just strikes me that if this was injected in a page inline, it would appear much the same as a DOM0 attribute. It is perception in some cases that drives adoption so if this is the final syntax we should be prepared to offer the explanation you have given in the least case. It still looks a bit like inline JS to someone who spent years convincing people to stop doing that and learn "unobtrusive"

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Mar 31, 2014

Contributor

In terms of adoption, I'm not very concerned. This is a big part of the reason why people use Angular. I believe Plolymer's Model-driven-views do something similar.

prepared to offer the explanation

You're very right about this. I've given this explanation a few times, but I think the people who need it are a small group (knowledgeable/experienced enough to see a similarity with it and DOM0, but not experienced with Angular / Polymer to know why it's different). And I think the people who hear it, understand it.

Contributor

justinbmeyer commented Mar 31, 2014

In terms of adoption, I'm not very concerned. This is a big part of the reason why people use Angular. I believe Plolymer's Model-driven-views do something similar.

prepared to offer the explanation

You're very right about this. I've given this explanation a few times, but I think the people who need it are a small group (knowledgeable/experienced enough to see a similarity with it and DOM0, but not experienced with Angular / Polymer to know why it's different). And I think the people who hear it, understand it.

@stevenvachon

This comment has been minimized.

Show comment
Hide comment
@stevenvachon

stevenvachon Mar 31, 2014

Contributor

Having spent the last number of years keeping my JavaScript out of my HTML, I'm even a little against the concept of can-EVENT despite its huge benefits. Adding arguments is a logical extension of the current API, however, and I'll most probably use it.

<div can-click="{{removeFrom parent child}}"></div>

I think that this is kind of strange because can-click="removeFrom" is already CanJS-specific. A rewrite such as the following may be more Handlebars-standard:

<div {{can-click removeFrom parent child}}></div>
Contributor

stevenvachon commented Mar 31, 2014

Having spent the last number of years keeping my JavaScript out of my HTML, I'm even a little against the concept of can-EVENT despite its huge benefits. Adding arguments is a logical extension of the current API, however, and I'll most probably use it.

<div can-click="{{removeFrom parent child}}"></div>

I think that this is kind of strange because can-click="removeFrom" is already CanJS-specific. A rewrite such as the following may be more Handlebars-standard:

<div {{can-click removeFrom parent child}}></div>
@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Mar 31, 2014

Contributor

{{can-click removeFrom parent child}} brings things full circle. This was already possible in 1.1.8. `can-click="foo(bar)" is much much more understandable in my opinion. And imo, worth the cost of a little confusion if it contrasts with how values get passed to can.Component.

Contributor

justinbmeyer commented Mar 31, 2014

{{can-click removeFrom parent child}} brings things full circle. This was already possible in 1.1.8. `can-click="foo(bar)" is much much more understandable in my opinion. And imo, worth the cost of a little confusion if it contrasts with how values get passed to can.Component.

@shcarrico

This comment has been minimized.

Show comment
Hide comment
@shcarrico

shcarrico Mar 31, 2014

Contributor

Are we opposed to x-event-click="remove" x-event-data="parent,child" ? This looks more like valid attributes from my perspective. If this was inline it wouldn't look as scripty. I like idea of x- or data - . Barring that we could explore can-event-click ie explicit add event vs short but maybe less obvious syntax? For scope could be x-scope-foo="bar" where x could be x,data or can and still follow the pattern.

Contributor

shcarrico commented Mar 31, 2014

Are we opposed to x-event-click="remove" x-event-data="parent,child" ? This looks more like valid attributes from my perspective. If this was inline it wouldn't look as scripty. I like idea of x- or data - . Barring that we could explore can-event-click ie explicit add event vs short but maybe less obvious syntax? For scope could be x-scope-foo="bar" where x could be x,data or can and still follow the pattern.

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Mar 31, 2014

Contributor

In my opinion, that is less obvious and harder to read.

I don't think can-click is less obvious than can-event-click.

Contributor

justinbmeyer commented Mar 31, 2014

In my opinion, that is less obvious and harder to read.

I don't think can-click is less obvious than can-event-click.

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Mar 31, 2014

Contributor

@matthewp 's comments here: #730 (comment) are related to this discussion.

Contributor

justinbmeyer commented Mar 31, 2014

@matthewp 's comments here: #730 (comment) are related to this discussion.

@sporto

This comment has been minimized.

Show comment
Hide comment
@sporto

sporto Apr 1, 2014

Contributor

Also related to this #631
At the moment it is ambiguous if you are passing a string or an object to a component

Contributor

sporto commented Apr 1, 2014

Also related to this #631
At the moment it is ambiguous if you are passing a string or an object to a component

@shcarrico

This comment has been minimized.

Show comment
Hide comment
@shcarrico

shcarrico Apr 14, 2014

Contributor

So to summarize, when passing a value to a component from the parent scope, should we use:

  1. <myTag foo="bar"></myTag>
  2. <myTag foo={bar}></myTag>
  3. <myTag foo="{{bar}}"></myTag>

I like the single {} option (2), as it disambiguates this from a standard mustache. The single braces syntax is used in http://facebook.github.io/react/, and I think it reads very easily as "pass a reference to this variable" vs "result of this variable is output into the tag here" ala {{}}

To take this further, <myTag foo={bar} can-click={handler(baz,bat)} ></myTag> clears things up in my mind. The things in the {} are scope properties, not string literals. It is the similarity to a string literal that makes me object strongly to choice 1 above.

Contributor

shcarrico commented Apr 14, 2014

So to summarize, when passing a value to a component from the parent scope, should we use:

  1. <myTag foo="bar"></myTag>
  2. <myTag foo={bar}></myTag>
  3. <myTag foo="{{bar}}"></myTag>

I like the single {} option (2), as it disambiguates this from a standard mustache. The single braces syntax is used in http://facebook.github.io/react/, and I think it reads very easily as "pass a reference to this variable" vs "result of this variable is output into the tag here" ala {{}}

To take this further, <myTag foo={bar} can-click={handler(baz,bat)} ></myTag> clears things up in my mind. The things in the {} are scope properties, not string literals. It is the similarity to a string literal that makes me object strongly to choice 1 above.

@retro

This comment has been minimized.

Show comment
Hide comment
@retro

retro Apr 14, 2014

Contributor

I agree, option 2 looks the best. It doesn't look like a string literal, and it doesn't look like a mustache expression which makes it (IMO) a perfect choice.

Contributor

retro commented Apr 14, 2014

I agree, option 2 looks the best. It doesn't look like a string literal, and it doesn't look like a mustache expression which makes it (IMO) a perfect choice.

@zkat

This comment has been minimized.

Show comment
Hide comment
@zkat

zkat Apr 14, 2014

Contributor

Note that unquoted attributes are perfectly valid html5, so foo={bar} and foo="{bar}" are equivalent to the browser.

Contributor

zkat commented Apr 14, 2014

Note that unquoted attributes are perfectly valid html5, so foo={bar} and foo="{bar}" are equivalent to the browser.

@ccummings ccummings added this to the 2.1.0 milestone Apr 25, 2014

@moschel

This comment has been minimized.

Show comment
Hide comment
@moschel

moschel Apr 25, 2014

Contributor

I agree, so <myTag foo={bar}></myTag> is what we'll do. I think Justin is working on this so assigning to him.

Contributor

moschel commented Apr 25, 2014

I agree, so <myTag foo={bar}></myTag> is what we'll do. I think Justin is working on this so assigning to him.

@moschel moschel assigned justinbmeyer and unassigned moschel Apr 25, 2014

@justinbmeyer justinbmeyer changed the title from Change syntax for passing in template objects to Components to use `{{}}` to Change syntax for passing in template objects to Components to use `{}` Apr 26, 2014

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