Attribute vs. Property Bindings

1,513 views
Skip to first unread message

Justin Fagnani

unread,
Jun 28, 2013, 9:57:39 PM6/28/13
to polymer-dev, web-ui
We were discussing non-string attribute bindings today and the implications for interop between custom elements and other frameworks that implement bindings like Angular, specifically how a framework might start allowing users to use custom elements that expect non-String bindings.

I hope I have all this right, so correct me if I get something wrong...

One of the problems with non-String valued bindings is that a framework has no way of knowing which bindings should convert the value to a string and set an attribute and which should set a property.

It sounds like Polymer handles this with the attributes attribute that lets Polymer know which attribute bindings are properties. There are also attribtues on existing element which are known to be used for property bindings, like SelectElement's selectedIndex. These are implemented by overriding bind(). Do I have that right?

If so, it also sounds like communicating that mapping of attribute->property needs to be a cross-framework feature, maybe at the MDV level. One idea is that there's a different syntax for binding to properties. Maybe via special names like property-selected-index="", this.selected-index="", or ::selected-index="".

Has this issue been discussed before? Is there a possibility of dealing with this at a lower-than-Polymer level?

Thanks,
  Justin

Scott Miles

unread,
Jun 28, 2013, 10:34:50 PM6/28/13
to Justin Fagnani, polymer-dev, web-ui
This is a tricky but very important question. I hope I can dispel some of the FUD around this issue, please let me know if what follows is not clear.

The ideal mental model for custom elements is that they are not special. Elements are elements. You interact with a custom element via attributes, properties, methods, and DOM api, just like any traditional element. If a particular element has an 'items' property that takes an Array, that element is agnostic to how that property receives a value.

The DOM is the framework, and DOM has no inherent binding concept. So, when you are using bindings, this necessarily implies some kind of binding engine, of which there are many. 

Of course, Polymer has a binding engine (built on MDV). However, what this means is that a Polymer element is using Polymer binding *internally*. These semantics do not leak, they are not something the user of the element need concern themselves with (again, the element itself is `plain`).

This is A Good Thing because it means I can make a Polymer element that composes assorted elements using Polymer binding regardless of what kind of elements I composed. But it also means I can use Tool X to work with a bunch of Polymer elements. Any internal Polymer binding work is hidden and irrelevant to Tool X.

The goal is to allow elements to be heterogeneous and allow DOM itself to be the lingua franca.

We were very excited the first time we saw X-Tags co-operating with Polymer elements because it proved this idea was possible.

WDYT?

Scott



--
 
---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.
Visit this group at http://groups.google.com/group/polymer-dev.
To view this discussion on the web visit https://groups.google.com/d/msgid/polymer-dev/CAEKsHmCBFffT3JcB0ptESSQr7kTHkn2g54Rvj0O-da630tLxZA%40mail.gmail.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Igor Minar

unread,
Jun 29, 2013, 9:51:33 AM6/29/13
to Scott Miles, Justin Fagnani, polymer-dev, web-ui, Miško Hevery
(Apologies guys! This email turned out to be much longer than what I intended, but it sums up several weeks of discussions and years of experience from our work on angular. I hope you find it worthy reading.)



Scott, I don't think that you are addressing the issue that Justin brought up, or I just didn't find the answer I was looking for.

You are right that custom elements should look and behave just like normal elements, that's all good.

The issue we are discussing is having a clear mental and syntactical model that would allow us to bind to element attributes (we have that with {{ }}-style bindings) as well as element properties (we feel like we don't have this). This is regardless of whether the element is custom or native.

Let me describe the current situations on MDV code examples:



Example A: Let's take an example of a simple binding:

<input placeholder="{{ myPlaceholder }}">

This binding is as simple as it gets. The double curly syntax here represents one-way data binding (live string interpolation).

Responsibilities:

1/ observe the expression, evaluate the value, serialize it to a string and update the place in the DOM marked with the double-curly with this string.


Example B: Now let's look at how we bind to a value:

<input value="{{ name }}">

Interesting this looks the same, but it means something completely different. The double curly syntax here represents two-way data-binding for string-only values for element attribute.

Responsibilities:

1/ same as example A 1/ except that we can't do interpolation because what would <input value="foo {{ name }} bar"> even mean?
2/ register a callback for the input event that will update the path we are binding to with a string (regardless of what the original data source type was

A bit weird but, I can live with that. It makes me sad however that the two way data-binding is element specific, so each element will have to implement it's own way of dealing with two-way data-binding and there won't be a common formatter/parser/validation pipeline that elements (custom or native) could opt-into and expose a unified api for these common processes.


Example C: Let's take a look at how we two-way databind to the select element:

<select selectedIndex="{{ selected }}">
  ...
</select>

Wait a second, selectedIndex is not even an attribute, it's a property. So you've created a custom non-standard attribute that holds information in the template about binding to a property. The double curly syntax here represents two-way data-binding for arbitrary-type values for element property.

Responsibilities:

1/ Observe the expression and update the property of the element without any kind of serialization whenever the expression value changes
2/ Observe the internal state of the select box and if a new item is selected propagate the new selected index value (number) into the model at path designated by the expression.

Whoa, this is super weird as the meaning of double curly means something quite different from example A and B. As a reader of this template code, I have no way of telling (especially for custom elements) what using double curly on this element does.


Example D: Let's bind to a class attribute:

<div class="{{ someClass }}"></div>

This looks a lot like 1/ but is a lot more complicated internally (or at least it should be) because instead of just simply writing to the class attribute, the binding should support string and arrays of strings as the input and then use Element.classList.add and Element.classList.remove to add or remove classes without affecting classes added to the element by other code. The double curly syntax here represents one-way data-binding for values of specified type to a complex data structure of the element.

Responsibilities:

1/ similar to example A 1/ but the serialization of values is more complex and instead of updating an attribute value, we should be updating a complex data structure exposed as an element property


So there you have it, 4 examples of bindings that look the same but semantically mean and do something very different.


That brings us back to the issue that Justin raised: how do we deal with binding to element properties (not attributes) with values of arbitrary type (not just strings)? This really is responsibility of MDV and not of elements (custom or native). Elements should just observe their properties and react to value mutations.

MDV should provide:

1/ clear syntax that distinguishes binding to an attribute (string interpolation or "binding by string") from binding to a property ("binding by reference") as well as one-way data-binding from two-way data-binding
2/ the glue for one-way data-binding: observing an expression and updating elements attribute or value
3/ the glue for two-way data-binding: same as 2/ but in both directions
4/ common formatter/parser/validation pipeline for two way data-binding that all elements could use




I'm appending some lessons we learned on Angular to provide more context behind these requirements:

1/ in angular double curly always means one-way data-binding to an element attribute (or textContent) with an interpolated string - that's what example A showcases. This has worked very well for us.

2/ two-way data-binding in angular is done via a special attribute ng-model that takes an expression. The example code B can be rewritten to angular as:

MDV:     <input value="{{ name }}">
Angular: <input ng-model="name">

ng-model attribute is one of our core directives for data-binding that represents an element-agnostic pipeline for formatting, parsing and validation. We then have element specific directives that hook into this pipeline in element specific way (e.g. checkbox, select, etc) this means that a single validator or formatter can be used with various elements without needing to know anything about the internal of this element. It also means that any custom element in angular can use the very same pipeline and for example became part of a validation constraints in a form.

This has been extremely powerful for angular apps.

3/ bindings to complex data structures like classList are dealt with using a combination of ng-class directive and double-curly binding. Double-curly binding can handle simple string interpolation use-cases, while ng-class directive handles arrays and maps as input. Both ensure that classes added either as literal strings in the class attribute as well as those added via dom manipulation at runtime are preserved (important for 3rd party widgets). Basically we make template like this one just work without surprises:

<div class="someHardcodedClass {{ myDynamicClass }} anotherOne" ng-class=" someArrayOrObjectWithClasses "></div>

Paying attention to all weird corner cases pays off in developer productivity.

4/ two-way data-binding for select element is really tricky to get right. especially when multi-list, option groups and nested options come into play. we use our ng-model pipeline for the shared stuff and lots of custom code that accounts of the complex internal state of the select element. The key here is that developers don't care what index is selected, but rather what's the value of the selected element(s) - these values should not be limited just to strings. Current MDV allows binding only to selectedIndex which is completely useless in practice.

The whole thing gets really ugly and it barely works in angular. We had to come up with a special ng-options directive to handle some corner-cases. This directive should be used instead of repeater for nested options elements in some complex cases. I think that we got to the point where we could refactor the code to support nested options repeater and cover all use-cases without ng-options, but just thinking of this code gives me the hibigeebies.

5/ binding to element properties is not directly supported by angular as we don't expose component api via dom api but rather via a javascript object. this is currently one of the fundamental differences between angular components and web components. we'll need to change this if we want angular components to interoperate with other components.

Having said that, we do have a concept of binding an external model (application model) to an internal model (component model). This is done automatically by angular based on the directive (component) configuration.

For example: <profile user="loggedInUser">

When angular comes across this element, it looks up it's definition and it will most likely see something like:

myModule.directive('profile', function() {
  restrict: 'E',
  scope: { user: '=' },
  template: '<div>User: {{user.name}}</div>'
});

This is a super lame implementation, but I'm keeping it simple on purpose. The important bits are in bold. Notice how in our app, we said that the input called "user" for our profile element comes from our application model loggedInUser. This value is not interpolated because we don't want to serialize the potentially complex user data structure into string. We want to pass it in by reference and this is what the '=' symbol in directive scope definition means. Lastly, since the internal name model name matches the attribute name, we can simply refer to the user.name in the template of our profile component.

The important take away is that binding by reference is important and it's very different from interpolation.

Based on developer feedback we also realized that the syntax for binding by reference in angular templates is not ideal, because it's indistinguishable from regular values that are not mean to be evaluated. 

Take this example:

<profile class="{{loggedInUser.theme}}" user="loggedInUser"  id="loggedInUser">

Here we are dealing with three attributes, each having it's value processed in a different way, but from the template alone you can't tell that because the last two attributes look the same.

The first attribute class, has it's value evaluated and interpolated into the dom - that's good. The last one - id - is just a plain old value that the attribute is set to and has meaning to CSS and dom apis, but doesn't affect the internal state of the component in any way. The user attribute however is component specific, and as mentioned before will be data-bound as "binding by reference", but this is not clear from the template and developer has to get familiar with the component definition to understand this.

Now if we we went with the current MDV syntax, the template would look like this:

<profile class="{{loggedInUser.theme}}" user="{{loggedInUser}}"  id="loggedInUser">

ok, so {{loggedInUser}} tells the developer that loggedInUser is an expression, but the information about how the result of the expression will affect the component is missing and as mentioned before the double-curly syntax makes this look like a string interpolation which it is not.

I'm curious what you guys think of this problem. Code readability is an important factor in many of our decisions in angular and having this kind of ambiguity really bothers me.

One of the solutions we are toying with is prefixing all non-interpolated expressions in attribute values with some kind of symbol. For example:

<profile class="{{loggedInUser.theme}}" user=":loggedInUser"  id="loggedInUser">

This would explicitly state that the attribute value is an expression, but makes it look clearly different from interpolation.

Related to this is i18n and translations strings. As Rafael correctly stated on this list before, i18n is a problem orthogonal to data-binding, but MDV should try to tackle it (eventually). Once it does, we'll need a way to distinguish user readable strings that should be i18n-ed from other strings in the template. I have a feeling that we are starting to run out of special symbols :-)

cheers,
Igor



Miško Hevery

unread,
Jun 29, 2013, 10:39:28 AM6/29/13
to Igor Minar, Scott Miles, Justin Fagnani, polymer-dev, web-ui
Awesome write up Igor. It is long because it is complicated.

Scott Miles

unread,
Jun 29, 2013, 1:47:26 PM6/29/13
to Miško Hevery, Igor Minar, Justin Fagnani, polymer-dev, web-ui
There's a lot of groovy information in their Igor, thanks for the write-up.

However, I think there is a communication problem wrt to the scope of the problem. When the OP says:

>> the implications for interop between custom elements and other frameworks that implement bindings

Then any discussion of a particular syntax goes out the window: we can impose no such syntax at the stated interop level. 

For example, one may be using some completely new concept that has nothing to do with attributes or markup. Maybe you are transpiling Elm, or some other cool new language.

Seems like what you are guys are talking about is the specific nature of MDV syntax and the way Polymer extends (abuses?) it. This is completely fair game, but is an orthogonal problem from arbitrary interop.

If there is an effort to standardize the industry on some (markup-related?) binding syntax, that's fine too, but that has to be clarified. This is not something Polymer is trying to promote necessarily.

If I misunderstood the scope of the question, my bad, but IMO I'm nervous about scaring away people from the core primitives (Web Components) by immersing them too much in the optional bits (MDV, Polymer).

Justin Fagnani

unread,
Jun 29, 2013, 3:11:06 PM6/29/13
to Scott Miles, Miško Hevery, Igor Minar, polymer-dev, web-ui
On Sat, Jun 29, 2013 at 10:47 AM, Scott Miles <sjm...@google.com> wrote:
There's a lot of groovy information in their Igor, thanks for the write-up.

However, I think there is a communication problem wrt to the scope of the problem. When the OP says:

>> the implications for interop between custom elements and other frameworks that implement bindings

Then any discussion of a particular syntax goes out the window: we can impose no such syntax at the stated interop level. 

Yep, there's a communication problem :) I'm not talking about standardizing the syntax, far from it. Just recognizing that different frameworks out there implement bindings and currently allow binding data to HTML attributes with some framework-specific way of binding to properties or property/event pairs. The syntax will be defined by the framework, and the component, if it's acting like a standard element should hopefully not have to be especially aware that it's being bound. But the framework still needs a way to tell when the declaration of a binding in the markup is attempting to bind to a property, not an attribute. Right now Polymer has it's own way of doing this that other frameworks will have to reverse engineer to be compatible with. I haven't looked at the x-tags interop, but my guess is that the bindings are only to string-valued attributes, not to arbitrarily valued properties.

Let me try to clarify with a concrete example. Imagine I write a data table Polymer element. It has a few attributes that can be set in markup, but it also has a tableDataProvider property, which it not an attribute, but an object with some functions for retrieving a page of data, getting the number of pages, and so on. We'd like to use this table in an Angular app. Angular sees it as just an element, which is fine for binding the attributes, but we'd also really like to declaratively bind the tableDataProvider to something.

Maybe it would look like this:
<data-table table-data-provider="{{ myDataProvider }}>
 
except that Angular has no way of knowing that table-data-provider is not an attribute, but a property and to set the value accordingly. Right now Angular and other frameworks would rightly try to convert the object to a string and set the attribute. In Polymer you use the "attributes" attribute to solve this internally. In MDV elements have overridden bind(), and a custom MDV syntax can add special handling for any element type or attribute, which is how the style and class attributes are handled.

So that's the problem.

The possible solution I was throwing out there, just to get ideas rolling, is not standardizing on the binding syntax, but standardizing via convention the attribute name to use to represent that the binding is to a property and not an attribute. It's similar to the ? at the end of an attribute name to denote that the attribute should have boolean behavior. An attribute name starting with "this." or just "." would mean you're binding to a property. Of course this can be done by the framework, but it would be great if MDV itself and Polymer supported something like this so that it's not a unique solution in each framework to a common problem.

Is that a little more clear? And if so, is it something worth coordinating on?

Cheers,
  Justin

Scott Miles

unread,
Jun 29, 2013, 4:04:22 PM6/29/13
to Justin Fagnani, Miško Hevery, Igor Minar, polymer-dev, web-ui
 
But the framework still needs a way to tell when the declaration of a binding in the markup is attempting to bind to a property, not an attribute. Right now Polymer has it's own way of doing this that other frameworks will have to reverse engineer to be compatible with. I haven't looked at the x-tags interop, but my guess is that the bindings are only to string-valued attributes, not to arbitrarily valued properties.

This is precisely the line of thinking I'm trying to ward off. There is no concept of bindings at the element layer. 

Polymer does not leak any semantic around using attributes to bind to properties. There is no such concept and nothing to reverse engineer.

This is exactly the thing I'm having a hard time making clear.

If some element has an Array valued `items` property, that's a *property*. Polymer defines a mechanism for declaring property mappings via attributes, but that mechanism only makes sense in Polymer. It may look like the element itself has some magic attribute that does binding, but this is not the case.

If you want to access `items` property using any other framework or mechanism, that's great, go for it. There is nothing special about the element as an instance. 

> except that Angular has no way of knowing that table-data-provider is not an attribute, but a property

As you described it, the object has a property tableDataProvider. There is no concept of 'table-data-provider' as an attribute, you made that up. 

Yes, the user of element X must know what the properties of that object are, but if your framework is going to allow using attributes as a command to bind data to properties, the framework must provide a syntax for that. The underlying element X has nothing to say about it.

In other words, for any particular element (e.g. input), you must know that you cannot access `value` as an attribute, but only as a property.

>> standardizing via convention the attribute name

This implies the attribute names are somehow discoverable, which they are not. IOW, if I make the example object you described above, I will document that it has a `tableDataProvider` property, but not that it has any kind of attribute for this concept. An object-valued attribute makes no sense in the first place. There is no attribute in my docs, and nothing for me to name conventionally.

I expect you are imagining Polymer code that looks like this: '<x-foo tableDataProvider="{{provider}}">. We can discuss whether this is a good idea or not, but to Polymer this is a directive to bind `provider` (property) and `tableDataProvider` (property). Again, this construction only works inside of a Polymer template. Outside of polymer, `tableDataProvider` is just a regular attribute and you wouldn't be able to use it for anything useful and it should not be documented.

Scott

Igor Minar

unread,
Jun 29, 2013, 4:18:30 PM6/29/13
to Justin Fagnani, Scott Miles, Miško Hevery, polymer-dev, web-ui
On Sat, Jun 29, 2013 at 12:11 PM, Justin Fagnani <justin...@google.com> wrote:



On Sat, Jun 29, 2013 at 10:47 AM, Scott Miles <sjm...@google.com> wrote:
There's a lot of groovy information in their Igor, thanks for the write-up.

However, I think there is a communication problem wrt to the scope of the problem. When the OP says:

>> the implications for interop between custom elements and other frameworks that implement bindings

Then any discussion of a particular syntax goes out the window: we can impose no such syntax at the stated interop level. 

Yep, there's a communication problem :) I'm not talking about standardizing the syntax, far from it. Just recognizing that different frameworks out there implement bindings and currently allow binding data to HTML attributes with some framework-specific way of binding to properties or property/event pairs. The syntax will be defined by the framework, and the component, if it's acting like a standard element should hopefully not have to be especially aware that it's being bound. But the framework still needs a way to tell when the declaration of a binding in the markup is attempting to bind to a property, not an attribute.

Why does a framework need to know about this? Framework should not care about internals of a component. If DOM Element is the api where everyone meets, then a framework should just enable the developer to interact with this DOM api.

Let's say that a polymer element exposes an attribute, property, a method and is an event target for some type of event. A framework like angular just needs to enable reaching all of these kids of apis via data-binding or otherwise. The framework doesn't need to know about what's the type of api it's talking to. That's the developers job. Developer needs to know that this particular component exposes attribute foo, property bar, etc. The framework should just enable reaching all of these apis in the right way.


 
Right now Polymer has it's own way of doing this that other frameworks will have to reverse engineer to be compatible with.

If we agree on all types of apis that an element exposes then there is nothing to be reverse engineered. The element just needs to be documented so that the developer knows how to use it.

Now there is a separate issue of being able to introspect the api, so that for example IDEs and RAD tools can use reflection generate a meaningful UI for interacting with an element. But I don't think that that's what we are trying to solve now.

/i

Igor Minar

unread,
Jun 29, 2013, 4:22:15 PM6/29/13
to Scott Miles, Justin Fagnani, Miško Hevery, polymer-dev, web-ui
I'm with Scott on this. Thinking more about the problem I'm starting to realize that as long as we agree on types of apis that an element can expose (attribute, property, event, etc), we should be golden.

My longish email should still however serve as a recommendation for a syntax change in MDV - but again this has nothing to do with custom elements as they should not care about the syntax, instead they should just care about types of apis they can expose.

/i

Justin Fagnani

unread,
Jun 29, 2013, 7:49:01 PM6/29/13
to Scott Miles, Miško Hevery, Igor Minar, polymer-dev, web-ui
On Sat, Jun 29, 2013 at 1:04 PM, Scott Miles <sjm...@google.com> wrote:
 
But the framework still needs a way to tell when the declaration of a binding in the markup is attempting to bind to a property, not an attribute. Right now Polymer has it's own way of doing this that other frameworks will have to reverse engineer to be compatible with. I haven't looked at the x-tags interop, but my guess is that the bindings are only to string-valued attributes, not to arbitrarily valued properties.

This is precisely the line of thinking I'm trying to ward off. There is no concept of bindings at the element layer. 

I'm not saying there is, but that there are bindings at the framework layer that use elements. The framework needs to determine if a binding is supposed to be to an attribute or a property or an event handler. There's an entire section of the Polymer documentation that talks about how it does this, via the "attributes" attribute (or the publish property) and the "on-" prefix for events.

I'm not claiming that elements are aware of bindings (outside of Node.bind()), but that the binding system needs to be aware of either the properties, to distinguish them from attributes, or have some kind of attribute name -> attribute/property/event encoding. Polymer actually does both:

1) For properties there no special encoding of the property name, but the "published properties" are declared and when an attribute is used with that name the binding is setup to the property. http://www.polymer-project.org/polymer.html under "Published Properties"

2) For event handlers there's an encoding via the "on-" prefix that maps the attribute name to the event name. http://www.polymer-project.org/polymer.html under "Declarative event mapping"

There's even an example of how published properties enable one element to bind an object-valued property of another element with the <visitor-creds> example.

So Polymer has solved this problem internally, and other frameworks will need to as well. What the documentation doesn't make clear is what happens when Polymer binds to a an attribute with the same name as a property that's not "published", as would happen with a Polymer component that uses a non-Polymer component. In that case does Polymer 1) bind to the attribute or 2) see that there's a property of the same name and bind to it?

This is the same problem that another framework would face if consuming a Polymer object. How is it supposed to tell if the attribute name refers to an attribute or a property? It could either use one of the two above strategies, reverse engineer the Polymer property publishing mechanism, or invent an encoding similar to the even encoding to clearly distinguish between attributes and properties.
 
Polymer does not leak any semantic around using attributes to bind to properties. There is no such concept and nothing to reverse engineer.

If a framework wants to know which properties were "published" they would. This would be if it wants to automatically map from attribute name -> property and support using Polymer customer elements.
 
This is exactly the thing I'm having a hard time making clear.

If some element has an Array valued `items` property, that's a *property*. Polymer defines a mechanism for declaring property mappings via attributes, but that mechanism only makes sense in Polymer. It may look like the element itself has some magic attribute that does binding, but this is not the case.

If you want to access `items` property using any other framework or mechanism, that's great, go for it. There is nothing special about the element as an instance. 

> except that Angular has no way of knowing that table-data-provider is not an attribute, but a property

As you described it, the object has a property tableDataProvider. There is no concept of 'table-data-provider' as an attribute, you made that up. 

As an example of encoding a camelCase property name in a case-insensitive attribute name, which is how Dart's Web UI does this. I should have been more clear there.
 

Yes, the user of element X must know what the properties of that object are, but if your framework is going to allow using attributes as a command to bind data to properties, the framework must provide a syntax for that. The underlying element X has nothing to say about it.

I didn't say the _element_ had something to say about it. I agree it is a concern of the framework, but it will be a concern of every framework and so far each framework has a very specific and not-amenable-to-interop way of handling this. Polymer uses "property publishing", Dart Web UI assumed that attribute names that matched public fields on the component class were property bindings. Angular seems to use directive here, but it seem like it might need a directive-per-property (Igor correct me if I'm wrong there). These break down when trying to use that framework to bind to an element property of a component not defined in that framework.
 
In other words, for any particular element (e.g. input), you must know that you cannot access `value` as an attribute, but only as a property.

>> standardizing via convention the attribute name

This implies the attribute names are somehow discoverable, which they are not.

No, it only implies that there's some kind of mapping from attribute name to property name. That could be via an encoding (such as the "this." prefix), so that the developer is responsible for using the correct attribute name. Because Polymer doesn't have such an encoding, but rather a special declaration of properties, I'm not sure that Polymer can bind to non-Polymer element properties.
 
IOW, if I make the example object you described above, I will document that it has a `tableDataProvider` property, but not that it has any kind of attribute for this concept. An object-valued attribute makes no sense in the first place. There is no attribute in my docs, and nothing for me to name conventionally.

The attribute would be special for the framework, not the element. The element is not adding or documenting an attribute, just a property, but the framework is seeing an attribute that is designated to be for a property binding.
 
I expect you are imagining Polymer code that looks like this: '<x-foo tableDataProvider="{{provider}}">. We can discuss whether this is a good idea or not, but to Polymer this is a directive to bind `provider` (property) and `tableDataProvider` (property). Again, this construction only works inside of a Polymer template. Outside of polymer, `tableDataProvider` is just a regular attribute and you wouldn't be able to use it for anything useful and it should not be documented.

Which brings me to the original question: How are custom elements from different frameworks supposed to interoperate for property bindings?

With the Polymer approach to property publishing, it doesn't look possible, unless Polymer is using one of the strategies I mentioned above. With a more generic approach, such as an encoding, I think it does. But Polymer (and x-tags) are pretty much leading the way in terms of building frameworks on top of the custom element standards and could provide some guidance here.

To get concrete again with the table example. Let's say that table element was implemented in pure custom elements with no Polymer and I want to use it and setup the data provider from within a Polymer element. Again, the element has a tableDataProvider, but no corresponding attribute. How would I set up a binding for it in Polymer?

Or we can talk about x-tags. It looks like they publish properties via the 'accessors' property, which can optionally also expose themselves as attributes too. How could Polymer bind to an x-tag property if it isn't published as an attribute?

Thanks for going back and forth with me!
  --Justin

Scott Miles

unread,
Jun 29, 2013, 9:09:45 PM6/29/13
to Justin Fagnani, Miško Hevery, Igor Minar, polymer-dev, web-ui
I urge you to re-read Igor's response. There is still a fundamental misunderstanding, and I believe he framed it more clearly than I did. 

It seems to me your thesis is that given some element that has an `items` attribute, how does framework X know that `items` refers to a (non string-valued) property and isn't just a plain old attribute.

The problem with that thesis is that there are no such problem attributes.

Example: here is my nifty new <x-filigree> component. It has an 'emboss' boolean attribute and a 'polisher' property. A 'polisher' is a special object that can polish things. 

Notice I described no 'polisher' attribute. There is no such thing. 

So, how can I bind an object to 'polisher'? That depends completely on your binding framework.

Polymer let's you bind to 'polisher' using attribute syntax, and this is where the confusion sets in. This usage only works in Polymer context and doesn't make sense in any other context. 

Another binding framework may use some completely other way of binding to the 'polisher' property (or may simply not support doing that).

>> Thanks for going back and forth with me!

Right back at you, thanks for your patience. :)

Scott

Justin Fagnani

unread,
Jun 29, 2013, 9:09:52 PM6/29/13
to Igor Minar, Scott Miles, Miško Hevery, polymer-dev, web-ui
On Sat, Jun 29, 2013 at 1:18 PM, Igor Minar <imi...@google.com> wrote:



On Sat, Jun 29, 2013 at 12:11 PM, Justin Fagnani <justin...@google.com> wrote:



On Sat, Jun 29, 2013 at 10:47 AM, Scott Miles <sjm...@google.com> wrote:
There's a lot of groovy information in their Igor, thanks for the write-up.

However, I think there is a communication problem wrt to the scope of the problem. When the OP says:

>> the implications for interop between custom elements and other frameworks that implement bindings

Then any discussion of a particular syntax goes out the window: we can impose no such syntax at the stated interop level. 

Yep, there's a communication problem :) I'm not talking about standardizing the syntax, far from it. Just recognizing that different frameworks out there implement bindings and currently allow binding data to HTML attributes with some framework-specific way of binding to properties or property/event pairs. The syntax will be defined by the framework, and the component, if it's acting like a standard element should hopefully not have to be especially aware that it's being bound. But the framework still needs a way to tell when the declaration of a binding in the markup is attempting to bind to a property, not an attribute.

Why does a framework need to know about this?

Because setting an attribute and setting a property are done differently, as is registering an event handler.
 
Framework should not care about internals of a component. If DOM Element is the api where everyone meets, then a framework should just enable the developer to interact with this DOM api.

But the DOM API includes attributes, properties and event handlers. The fact is that just about every template/binding syntax is overloading attribute names to refer to various parts of the element's API. There's nothing "internal" about the component that I'm advocating for the framework to be aware of.
 
Let's say that a polymer element exposes an attribute, property, a method and is an event target for some type of event. A framework like angular just needs to enable reaching all of these kids of apis via data-binding or otherwise.

Yep.
 
The framework doesn't need to know about what's the type of api it's talking to. That's the developers job. Developer needs to know that this particular component exposes attribute foo, property bar, etc. The framework should just enable reaching all of these apis in the right way.

Yep again. This is exactly what I'm advocating. Angular, or any framework, can solve this in whatever way it chooses, but so far what I'm seeing from Polymer and it appears x-tags too is that there's a framework-specific mechanism for declaring which attribute names refer to properties which is going to hinder interop because there's no general way to bind to properties.
 
Right now Polymer has it's own way of doing this that other frameworks will have to reverse engineer to be compatible with.

If we agree on all types of apis that an element exposes then there is nothing to be reverse engineered. The element just needs to be documented so that the developer knows how to use it.

I mostly agree, but still don't think this is strictly true in all cases if the framework doesn't syntactically distinguish between attributes and properties. Consider a name collision between an attribute and property, something like value for InputElement. The framework, when handling a binding to value has to decide whether to bind the attribute or property. If the framework is using Node.bind() I think it can just let the element decide, or it could special case it. But a Polymer element has already declared which properties are published, so if the framework wants to respect the component authors intent, it should be aware of the "attributes" attribute and the 'publish' property. Or so I think.
 
Now there is a separate issue of being able to introspect the api, so that for example IDEs and RAD tools can use reflection generate a meaningful UI for interacting with an element. But I don't think that that's what we are trying to solve now.

Not yet, but I agree that's very important too, for later.

Cheers,
  Justin

Justin Fagnani

unread,
Jun 29, 2013, 9:12:03 PM6/29/13
to Scott Miles, Miško Hevery, Igor Minar, polymer-dev, web-ui
On Sat, Jun 29, 2013 at 6:09 PM, Scott Miles <sjm...@google.com> wrote:
I urge you to re-read Igor's response. There is still a fundamental misunderstanding, and I believe he framed it more clearly than I did. 

It seems to me your thesis is that given some element that has an `items` attribute, how does framework X know that `items` refers to a (non string-valued) property and isn't just a plain old attribute.

The problem with that thesis is that there are no such problem attributes.

Example: here is my nifty new <x-filigree> component. It has an 'emboss' boolean attribute and a 'polisher' property. A 'polisher' is a special object that can polish things. 

Notice I described no 'polisher' attribute. There is no such thing. 

So, how can I bind an object to 'polisher'? That depends completely on your binding framework.

Polymer let's you bind to 'polisher' using attribute syntax

Can you describe how? As I see it Polymer will just attempt to set the attribute 'polisher'. I'm assuming that <x-filigee> is _not_ a Polymer component.

 
, and this is where the confusion sets in. This usage only works in Polymer context and doesn't make sense in any other context. 

Another binding framework may use some completely other way of binding to the 'polisher' property (or may simply not support doing that).

I agree. I'm just worried that so far these methods don't appear to be compatible, because there are framework-specific ways of publishing the properties.

Scott Miles

unread,
Jun 29, 2013, 9:30:25 PM6/29/13
to Justin Fagnani, Miško Hevery, Igor Minar, polymer-dev, web-ui
>> Can you describe how? As I see it Polymer will just attempt to set the attribute 'polisher'. I'm assuming that <x-filigee> is _not_ a Polymer component.

Yes, sorry, that is correct. It can only do that if <x-filigree> is a Polymer component.

>> I agree. I'm just worried that so far these methods don't appear to be compatible, because there are framework-specific ways of publishing the properties

There is nothing INcompatible. The notion of 'publishing' is handshaking that Polymer does with itself, it's not necessary for data binding in general.

Perhaps Polymer should have a more general syntax for binding to properties, but this is a feature question for Polymer, not any interoperability problem. If your binding layer has a way to bind to a data property (e.g. `ng-model`), that will work just fine with any element (including Polymer elements).

Justin Fagnani

unread,
Jun 29, 2013, 9:41:01 PM6/29/13
to Scott Miles, Miško Hevery, Igor Minar, polymer-dev, web-ui
On Sat, Jun 29, 2013 at 6:30 PM, Scott Miles <sjm...@google.com> wrote:
>> Can you describe how? As I see it Polymer will just attempt to set the attribute 'polisher'. I'm assuming that <x-filigee> is _not_ a Polymer component.

Yes, sorry, that is correct. It can only do that if <x-filigree> is a Polymer component.

>> I agree. I'm just worried that so far these methods don't appear to be compatible, because there are framework-specific ways of publishing the properties

There is nothing INcompatible. The notion of 'publishing' is handshaking that Polymer does with itself, it's not necessary for data binding in general.

Perhaps Polymer should have a more general syntax for binding to properties, but this is a feature question for Polymer, not any interoperability problem. If your binding layer has a way to bind to a data property (e.g. `ng-model`), that will work just fine with any element (including Polymer elements).

Right, so this is what I'm getting at. Instead of having framework-specific internal handshakes, maybe we should encourage property binding support in the syntax. Then we'll truly have interop at the property binding level. If everyone implements an internal mapping/handshake with an overloading of attribute names first, then _property_binding_ interop won't come until people try, fail and file a property binding syntax request.

If that happens, then there will be two different ways to bind to a property: publish it and overload the attribute name, or use the property binding support in the binding syntax. I'd suggest just removing the overloaded attribute name as an option.

I'll file an issue to track allowing property bindings on non-Polymer elements though.

Thanks Scott and Igor!
  -Justin

Justin Fagnani

unread,
Jun 29, 2013, 9:45:56 PM6/29/13
to Scott Miles, Miško Hevery, Igor Minar, polymer-dev, web-ui
On Sat, Jun 29, 2013 at 6:41 PM, Justin Fagnani <justin...@google.com> wrote:
On Sat, Jun 29, 2013 at 6:30 PM, Scott Miles <sjm...@google.com> wrote:
>> Can you describe how? As I see it Polymer will just attempt to set the attribute 'polisher'. I'm assuming that <x-filigee> is _not_ a Polymer component.

Yes, sorry, that is correct. It can only do that if <x-filigree> is a Polymer component.

>> I agree. I'm just worried that so far these methods don't appear to be compatible, because there are framework-specific ways of publishing the properties

There is nothing INcompatible. The notion of 'publishing' is handshaking that Polymer does with itself, it's not necessary for data binding in general.

Perhaps Polymer should have a more general syntax for binding to properties, but this is a feature question for Polymer, not any interoperability problem.

Oh, so the reason why I though that this might be something to consider for MDV, and not just Polymer, is that every binding system will have this problem, MDV too. If MDV doesn't support binding to properties and event handlers, then it's yet another indication (in addition to it's lack of expressions, filters, etc.) that the default MDV syntax isn't very useful. I suppose this can wait till the various frameworks have experiments with their own syntaxes.

Scott Miles

unread,
Jun 29, 2013, 11:25:23 PM6/29/13
to Justin Fagnani, Miško Hevery, Igor Minar, polymer-dev, web-ui
>> Right, so this is what I'm getting at. Instead of having framework-specific internal handshakes, maybe we should encourage property binding support in the syntax.

It's INTERNAL. It has no effect or usefulness at any other level. It has to do only with how we implemented our own binding.

When you say "in the syntax" what syntax do you mean?


>>  If everyone implements an internal mapping/handshake with an overloading of attribute names first,

What? I'm sorry, but this doesn't make any sense. You keep insisting there is some kind of interop problem, I'm saying there is not. 

Show me an example. So far none of your examples have actually demonstrated any problem.

>> If that happens, then there will be two different ways to bind to a property

There are infinite number of ways to 'bind to a property'. If you are talking about generating some kind of standard, that is a completely different question.

>> I'll file an issue to track allowing property bindings on non-Polymer elements though.

That's fine, but It's not at all clear that this is a good idea in general.

Scott


On Sat, Jun 29, 2013 at 6:41 PM, Justin Fagnani <justin...@google.com> wrote:
On Sat, Jun 29, 2013 at 6:30 PM, Scott Miles <sjm...@google.com> wrote:
>> Can you describe how? As I see it Polymer will just attempt to set the attribute 'polisher'. I'm assuming that <x-filigee> is _not_ a Polymer component.

Yes, sorry, that is correct. It can only do that if <x-filigree> is a Polymer component.

>> I agree. I'm just worried that so far these methods don't appear to be compatible, because there are framework-specific ways of publishing the properties

There is nothing INcompatible. The notion of 'publishing' is handshaking that Polymer does with itself, it's not necessary for data binding in general.

Perhaps Polymer should have a more general syntax for binding to properties, but this is a feature question for Polymer, not any interoperability problem. If your binding layer has a way to bind to a data property (e.g. `ng-model`), that will work just fine with any element (including Polymer elements).

Right, so this is what I'm getting at. Instead of having framework-specific internal handshakes, maybe we should encourage property binding support in the syntax. Then we'll truly have interop at the property binding level. If everyone implements an internal mapping/handshake with an overloading of attribute names first, then _property_binding_ interop won't come until people try, fail and file a property binding syntax request.

If that happens, then there will be two different ways to bind to a property: publish it and overload the attribute name, or use the property binding support in the binding syntax. I'd suggest just removing the overloaded attribute name as an option.

I'll file an issue to track allowing property bindings on non-Polymer elements though.

Thanks Scott and Igor!
  -Justin

<snip>

Scott Miles

unread,
Jun 29, 2013, 11:33:46 PM6/29/13
to Justin Fagnani, Miško Hevery, Igor Minar, polymer-dev, web-ui
>> Oh, so the reason why I though that this might be something to consider for MDV, and not just Polymer, is that every binding system will have this problem, MDV too

That's fine. Again, if your tool of choice has a syntax to allow binding to properties, then everything is fine. Whatever systems the element employs internally remain irrelevant.

Scott

On Sat, Jun 29, 2013 at 6:45 PM, Justin Fagnani <justin...@google.com> wrote:
On Sat, Jun 29, 2013 at 6:41 PM, Justin Fagnani <justin...@google.com> wrote:
On Sat, Jun 29, 2013 at 6:30 PM, Scott Miles <sjm...@google.com> wrote:
>> Can you describe how? As I see it Polymer will just attempt to set the attribute 'polisher'. I'm assuming that <x-filigee> is _not_ a Polymer component.

Yes, sorry, that is correct. It can only do that if <x-filigree> is a Polymer component.

>> I agree. I'm just worried that so far these methods don't appear to be compatible, because there are framework-specific ways of publishing the properties

There is nothing INcompatible. The notion of 'publishing' is handshaking that Polymer does with itself, it's not necessary for data binding in general.

Perhaps Polymer should have a more general syntax for binding to properties, but this is a feature question for Polymer, not any interoperability problem.

Oh, so the reason why I though that this might be something to consider for MDV, and not just Polymer, is that every binding system will have this problem, MDV too. If MDV doesn't support binding to properties and event handlers, then it's yet another indication (in addition to it's lack of expressions, filters, etc.) that the default MDV syntax isn't very useful. I suppose this can wait till the various frameworks have experiments with their own syntaxes.
If your binding layer has a way to bind to a data property (e.g. `ng-model`), that will work just fine with any element (including Polymer elements).

Right, so this is what I'm getting at. Instead of having framework-specific internal handshakes, maybe we should encourage property binding support in the syntax. Then we'll truly have interop at the property binding level. If everyone implements an internal mapping/handshake with an overloading of attribute names first, then _property_binding_ interop won't come until people try, fail and file a property binding syntax request.

If that happens, then there will be two different ways to bind to a property: publish it and overload the attribute name, or use the property binding support in the binding syntax. I'd suggest just removing the overloaded attribute name as an option.

I'll file an issue to track allowing property bindings on non-Polymer elements though.

Thanks Scott and Igor!
  -Justin

<snip>

Miško Hevery

unread,
Jun 30, 2013, 12:38:04 AM6/30/13
to Scott Miles, Justin Fagnani, Igor Minar, polymer-dev, web-ui
Ok, lets try a concrete example as proof by contradiction.

1) Imagine I implement <google-maps> tag. It has attributes width/height and it has a property position which corresponds to an object which has things like latitude, longitude, zoom level, etc. 
2) I implement this as a web-component, so for all practical purposes it acts like an Element. I can set its width/height attributes and I can read or write the position property to see where the user has zoomed into or effect what the user sees.
3) I want to use it in Polymer. How do I express that I want to make bi-directional binding to position property. I want to say something like this:
 <google-maps position="{{polymerObject}}" width="{{polymerWidth}}" height="{{polymerHeight}}">
This will work for attributes, but not for properties, since polymer:
   a) has no idea that position here refers to property not an attribute and 
   b) that the property needs to be kept in sync bidirectionally.

The reason why polymer (or any other framework for that matter) can not interoperate with this element is because someone needs to have knowledge of:
   a) position is property 
   b) binding is bidirectional. 

This information can either be 
  a) published by the component or 
  b) can be supplied by the framework during the registration process of the element or 
  c) can be implied from the binding syntax.

For example one way to solve this would be to come up with this syntax:
<google-maps position="[[polymerObject]]" width="{{polymerWidth}}" height="{{polymerHeight}}">

Here the information that position is property is implied by the syntax. The actual syntax is up for discussion, what I am getting at is that there needs to be a way to differentiate this.

Taking this one step further, how does this work if input was not written with MDV in mind.
<input type="radio" value="{{frameworkProprety}}">

If input is not aware of MDV or if it choses not to cooperate with MDV the whole thing fails to work. 

MDV should work in such a way, that any element can be bound to regardless if the element is aware of the MDV/Polymer/Or any other framework.

-- Misko


Justin Fagnani

unread,
Jun 30, 2013, 12:44:31 AM6/30/13
to Scott Miles, Miško Hevery, Igor Minar, polymer-dev, web-ui
On Sat, Jun 29, 2013 at 8:25 PM, Scott Miles <sjm...@google.com> wrote:
>> Right, so this is what I'm getting at. Instead of having framework-specific internal handshakes, maybe we should encourage property binding support in the syntax.

It's INTERNAL. It has no effect or usefulness at any other level. It has to do only with how we implemented our own binding.

When you say "in the syntax" what syntax do you mean?

I mean the binding syntax, which is of course probably part of the framework too, but there's a difference between the syntax supporting property bindings and the framework converting what look like attribute bindings, except for this internal handshake, into property bindings. By "in the syntax" I mean something like encoding a property name in an attribute name, or maybe something like Igor mention where it doesn't even use the double-braces.
 
>>  If everyone implements an internal mapping/handshake with an overloading of attribute names first,

What? I'm sorry, but this doesn't make any sense. You keep insisting there is some kind of interop problem, I'm saying there is not. 

You just agreed that Polymer can bind to properties of Polymer custom elements, but can not bind to properties of non-Polymer custom elements. How is that _not_ an interop problem?

Let's put out a few use cases to see if we're on the same page about what the current capabilities are regarding component reuse across frameworks:

1) A Polymer element can use another Polymer element and create a binding to it's published properties.
2) A Polymer element can use an x-tags element, but cannot create a binding to it's properties (accessors), because Polymer only supports property bindings when the properties are published via Polymer's internal convention.
3) An x-tag element can use a Polymer element, but ?? (there's not enough documentation and no comments in the code)

Point being that there are bindings that can be made between Polymer components that can't be made between a Polymer component and a plain element or custom element from pure MDV or another framework.

Is that much non-controversial?

-Justin

Matthew McNulty

unread,
Jun 30, 2013, 2:40:20 AM6/30/13
to Justin Fagnani, Scott Miles, Miško Hevery, Igor Minar, polymer-dev, web-ui

Apologies if jumping in here I have something incorrect. 

It seems to me what is being misunderstood here is Scott's point earlier that "the framework is DOM." Most of the misunderstanding seems to me to be related to some *other*, non-DOM framework needing information about interop. I can understand why this is a little strange to the world of Angular. 

One of the central tenets of Polymer is this concept. Polymer is a framework for creating custom elements. *Internal* to a custom element, you are in Polymer-land. *External* to an element you have to play by DOM rules, and what you all seem to be suggesting is adding new capabilities to DOM, which as Scott says is fine, but isn't something we see the need for currently. The barrier between the internal and external worlds has no leaking.

Where it gets a bit confusing is that in Polymer-land a custom element can be arbitrarily complex, up to and including a whole app. In this way you can construct a universe that is just Polymer, and the elements would indeed need to know about these APIs, but there would not be other frameworks involved, necessarily, so there isn't really an interop concern. 

But regardless, the interface between Polymer-land and non-Polymer-land is custom elements/DOM and that's it. I think people may be confusing elements that are meant to be internal with ones that would be external. 

So Miško, in your example, you are violating this construct by introducing API that is not standard to DOM, and necessarily would require some *other* framework besides DOM that knows about the google maps widget custom API. In order for interop to work, you need to play by the rules of the DOM, which has no such construct. 

Again, apologies if I am not understanding the disagreement here. 

-Matt


--
 
---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.
Visit this group at http://groups.google.com/group/polymer-dev.

Scott Miles

unread,
Jun 30, 2013, 3:17:28 AM6/30/13
to Matthew McNulty, Justin Fagnani, Miško Hevery, Igor Minar, polymer-dev, web-ui
Matt has hit it on the nose.

S

Scott Miles

unread,
Jun 30, 2013, 3:41:10 AM6/30/13
to Justin Fagnani, Miško Hevery, Igor Minar, polymer-dev, web-ui
>> 
1) A Polymer element
...
3) An x-tag element
<<

We shouldn't talk about this-or-that kind of element. When we say 'elements are elements', we mean it. If you need to differentiate about the tool or system that implements the element then you have broken interop.

This is the critical bit: one cannot say "a Polymer element binds" a certain way, it confuses the (internal) private implementation of that element with an (external) instance of the element. 

>> the current capabilities are regarding component reuse across frameworks:

As above, the notion that an instance of a Polymer element has 'polymer capabilities' is a misunderstanding.

I can use <your-elements> and you can use <my-elements>, there is no need to tell them apart.

You can use whatever binding framework you like, or none at all. If you are building an application, it's up to you what tools you use. If you are building your own custom element, those semantics will be encapsulate in the element scope.

Polymer does include a binding framework. It's specifically built to help *implement* custom elements. Right now, it has bugs and flaws. Using it is a choice you make freely: either way the resulting component can be used by anybody else.

Miško Hevery

unread,
Jun 30, 2013, 9:48:08 AM6/30/13
to Scott Miles, Justin Fagnani, Igor Minar, polymer-dev, web-ui
So I get all that you are saying. Element is element, how things are done internally is non-of your business. I get, I understand it, and I agree with it. Where the confusion starts is what Matt says.

> So Miško, in your example, you are violating this construct by introducing API that is not standard to DOM, 
> and necessarily would require some *other* framework besides DOM that knows about the google maps widget
> custom API. In order for interop to work, you need to play by the rules of the DOM, which has no such construct. 

Non-standard to DOM? Which part? Could you explain this better. Which construct are you referring to? That an element has properties? That is very standard. Look at <input> it has both value property and value attribute, and the two behave very different. 

When Polymer consumes an <input> (very much standard element) How exactly do you get Polymer to bind to value property bidirectionally rather than value attribute unidirectional?

-- Misko

Matthew McNulty

unread,
Jun 30, 2013, 2:36:11 PM6/30/13
to Miško Hevery, Scott Miles, Justin Fagnani, Igor Minar, polymer-dev, web-ui
I'll let Scott respond to the implementation question, but is it relevant? How Polymer handles this binding internal to Polymer doesn't seem related to whether something should be introduced to the web platform to handle this situation across elements external to a framework. . 

It's hard to debate solutions to a problem Scott and I are saying doesn't exist - I think this is the root of the confusion and I'm not sure we're managing to resolve it over email...


--
 
---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.
Visit this group at http://groups.google.com/group/polymer-dev.

Erik Arvidsson

unread,
Jun 30, 2013, 3:30:01 PM6/30/13
to Matthew McNulty, Miško Hevery, Scott Miles, Justin Fagnani, Igor Minar, polymer-dev, web-ui
On Sun, Jun 30, 2013 at 2:36 PM, Matthew McNulty <mmcn...@google.com> wrote:
On Sun, Jun 30, 2013 at 6:48 AM, Miško Hevery <mi...@google.com> wrote:

When Polymer consumes an <input> (very much standard element) How exactly do you get Polymer to bind to value property bidirectionally rather than value attribute unidirectional?


This is "hard coded" in MDV. 

I agree that it might make sense to allow MDV to bind to attributes as well as to properties. Also almost all data binding systems end up with one way bindings, bind once as well as two way binding. For MDV we wanted to keep things simple but I'm sure you agree with me that these are need sooner or later.

But, remember that you can use Angular to bind attributes and properties of a custom element that is implemented using Polymer. The implementation details do not matter.

Another thing to remember is that the attributes supported by an element (custom or builtin) are generally not discoverable. The properties (but not their type) are discoverable using reflection.

--
erik


Martijn Faassen

unread,
Jul 1, 2013, 9:20:40 AM7/1/13
to Scott Miles, Justin Fagnani, Miško Hevery, Igor Minar, polymer-dev, web-ui
Hey,

On Sat, Jun 29, 2013 at 10:04 PM, Scott Miles <sjm...@google.com> wrote:
> I expect you are imagining Polymer code that looks like this: '<x-foo
> tableDataProvider="{{provider}}">. We can discuss whether this is a good
> idea or not, but to Polymer this is a directive to bind `provider`
> (property) and `tableDataProvider` (property). Again, this construction only
> works inside of a Polymer template.

This means that x-foo is not useful outside a Polymer template - it's
only to be used to implement some other custom element that *is*
useful
outside Polymer.

So any custom elements that receive object properties through MDV (if
these are not attributes, why is the section called "Binding objects
to attribute values", by the way? I guess an attribute is still
involved..) are not reusable outside of MDV.

So the question would be whether Polymer needs a way to pass in
objects to elements in a reusable way. Is this something that is
useful? Is this something Polymer should support? If so, should this
be through an API or should it be possible through HTML?

In one way, Polymer already has a way to pass objects to an element:

<my-element foo="Foo" bar="Bar"></my-element>

passes an object with properties "foo" and "bar" to my-element. There
are some drawbacks though - I can't easily pass the object along to an
another element without retyping the whole thing in MDV, and how would
I pass in things like methods?

Regards,

Martijn

Martijn Faassen

unread,
Jul 1, 2013, 9:31:02 AM7/1/13
to Scott Miles, Justin Fagnani, Miško Hevery, Igor Minar, polymer-dev
Hey,

Responding to myself:

> So the question would be whether Polymer needs a way to pass in
> objects to elements in a reusable way. Is this something that is
> useful? Is this something Polymer should support? If so, should this
> be through an API or should it be possible through HTML?

I realized an API is of course already there; you can simply set the
property on the element. Correct?

So a question is whether those properties should be discoverable
(beyond documentation) - if they were, a non-MDV language can do
something similar to what MDV does with them. Just knowing what names
they have would be sufficient, I think? But of course that would be
going beyond what the DOM offers in some way.

(I've been trying to wrap my head around these topics myself, so this
discussion is helpful in wrapping a bit more; bits of topics are still
sticking out here and there..)

Regards,

Martijn

Justin Fagnani

unread,
Jul 1, 2013, 11:40:23 AM7/1/13
to Matthew McNulty, Miško Hevery, Scott Miles, Igor Minar, polymer-dev, web-ui
On Sun, Jun 30, 2013 at 11:36 AM, Matthew McNulty <mmcn...@google.com> wrote:
I'll let Scott respond to the implementation question, but is it relevant? How Polymer handles this binding internal to Polymer doesn't seem related to whether something should be introduced to the web platform to handle this situation across elements external to a framework. . 

It does in the sense that Polymer is the first framework to be built on MDV, and I'm under the impression that it's supposed to help refine the standards. Polymer has discovered a general problem (binding to properties) and solved it in a framework-specific way such that it only works when binding from one Polymer element to another Polymer element.

Yes, Polymer's implementation of property binding is "internal", and that's exactly the problem. That capabilities doesn't exist for bindings from Polymer elements to non-Polymer elements, thus there's (IMO) a deficiency in Polymer. This is a feature request on Polymer.

Additionally, because the problem is general, but the solutions so far have been framework specific, there appears to me to be a lack of conversation, convention, and possibly standardization around the problem. I'd go so far as to argue that the framework-specific solutions, like publishing properties, are an anti-feature and should be removed in favor of a general ability to bind to element properties regardless of whether the element is native, "pure MDV", or from some other framework. This is another feature request on Polymer, but there's also a request for at least guidance from MDV so that other frameworks don't special case this too.
 
It's hard to debate solutions to a problem Scott and I are saying doesn't exist - I think this is the root of the confusion and I'm not sure we're managing to resolve it over email...

Agreed. Hopefully we can meet in person soon.

Cheers,
  Justin

John Messerly

unread,
Jul 1, 2013, 2:58:06 PM7/1/13
to Matthew McNulty, Justin Fagnani, Scott Miles, Miško Hevery, Igor Minar, polymer-dev, web-ui
Apologies for coming late to this thread, or for any confusions on my part :)

On Sat, Jun 29, 2013 at 11:40 PM, Matthew McNulty <mmcn...@google.com> wrote:
Apologies if jumping in here I have something incorrect. 

It seems to me what is being misunderstood here is Scott's point earlier that "the framework is DOM." Most of the misunderstanding seems to me to be related to some *other*, non-DOM framework needing information about interop. I can understand why this is a little strange to the world of Angular. 

When we say "the framework is the DOM" do we mean:
  • DOM_now -- as it's spec'd now on WhatWG
  • DOM_MDV -- DOM_now plus MDV extensions, most importantly Node.bind and HTMLTemplateElement.model
  • DOM_future -- the DOM of the future, which may have MDV or some variation of it built-in?
Polymer elements expose properties via Node.bind (source). It seems important that "frameworks of the future" will use Node.bind to bind properties (using any syntax the framework desires).

On an unrelated point: it would be good if frameworks respect the <template> element. If I have MDV-style {{ bindings }} in my template contents, I don't want a framework to eagerly replace them with its own binding syntax interpretation. (In a worst case scenario, the framework could mess up the contents of a <polymer-element> before Polymer got to interpret them, which would break things).

Cheers!
- John

Scott Miles

unread,
Jul 1, 2013, 3:58:41 PM7/1/13
to John Messerly, Matthew McNulty, Justin Fagnani, Miško Hevery, Igor Minar, polymer-dev, web-ui
>> When we say "the framework is the DOM" do we mean:

Polymer requires Custom Elements to be (as if) part of DOM. Everything else that Polymer does is encapsulated inside Polymer elements.

Polymer requires nothing else from DOM, but also doesn't prevent anything else from being DOM. 

Adding data binding into DOM is a great discussion. Let's have that discussion (in a new thread please =P).

But any claims that Custom Elements do not interoperate somehow, or that Polymer elements are distinguishable from any other Custom Elements, will cause me to chime in and call FUD.

I don't want users to think that x-tags cannot play with polymer-elements, or that either cannot work with Angular, Ember, or whatever your tool of choice is. This universality of these elements is a core part of the design.

Scott

Justin Fagnani

unread,
Jul 1, 2013, 4:09:56 PM7/1/13
to Scott Miles, John Messerly, Matthew McNulty, Miško Hevery, Igor Minar, polymer-dev, web-ui
On Mon, Jul 1, 2013 at 12:58 PM, Scott Miles <sjm...@google.com> wrote:
>> When we say "the framework is the DOM" do we mean:

Polymer requires Custom Elements to be (as if) part of DOM. Everything else that Polymer does is encapsulated inside Polymer elements.

Polymer requires nothing else from DOM, but also doesn't prevent anything else from being DOM. 

Adding data binding into DOM is a great discussion. Let's have that discussion (in a new thread please =P).

But any claims that Custom Elements do not interoperate somehow, or that Polymer elements are distinguishable from any other Custom Elements, will cause me to chime in and call FUD.

I don't want users to think that x-tags cannot play with polymer-elements, or that either cannot work with Angular, Ember, or whatever your tool of choice is. This universality of these elements is a core part of the design.

I don't understand this claim. You just agreed earlier, with the <x-filigree> example, that Polymer could not bind to a property of a non-Polymer element:

Yes, sorry, that is correct. It can only do that if <x-filigree> is a Polymer component.

This is exactly the problem I'm trying to talk about.

John Messerly

unread,
Jul 1, 2013, 4:14:27 PM7/1/13
to Justin Fagnani, Scott Miles, Matthew McNulty, Miško Hevery, Igor Minar, polymer-dev, web-ui
On Mon, Jul 1, 2013 at 1:09 PM, Justin Fagnani <justin...@google.com> wrote:
On Mon, Jul 1, 2013 at 12:58 PM, Scott Miles <sjm...@google.com> wrote:
>> When we say "the framework is the DOM" do we mean:

Polymer requires Custom Elements to be (as if) part of DOM. Everything else that Polymer does is encapsulated inside Polymer elements.

Polymer requires nothing else from DOM, but also doesn't prevent anything else from being DOM. 

Adding data binding into DOM is a great discussion. Let's have that discussion (in a new thread please =P).

But any claims that Custom Elements do not interoperate somehow, or that Polymer elements are distinguishable from any other Custom Elements, will cause me to chime in and call FUD.

I don't want users to think that x-tags cannot play with polymer-elements, or that either cannot work with Angular, Ember, or whatever your tool of choice is. This universality of these elements is a core part of the design.

I don't understand this claim. You just agreed earlier, with the <x-filigree> example, that Polymer could not bind to a property of a non-Polymer element:

I think this would work if "x-filigree" implements Node.bind, right? Since Polymer uses DOM+MDV it should ultimately call Node.bind on that element. (It's up to the x-filigree element to implement Node.bind though.)

Steve Orvell

unread,
Jul 1, 2013, 4:23:11 PM7/1/13
to John Messerly, Justin Fagnani, Scott Miles, Matthew McNulty, Miško Hevery, Igor Minar, polymer-dev, web-ui
I don't understand this claim. You just agreed earlier, with the <x-filigree> example, that Polymer could not bind to a property of a non-Polymer element:

I believe the point Scott is making is that "bind to a property of" is not part of the DOM and therefore represents no core problem in how elements work together. 

This is exactly the problem I'm trying to talk about.

We just need to be clear that this is a data binding question, not a custom elements problem. 


--
 
---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.
Visit this group at http://groups.google.com/group/polymer-dev.

Miško Hevery

unread,
Jul 3, 2013, 10:15:34 AM7/3/13
to Steve Orvell, John Messerly, Justin Fagnani, Scott Miles, Matthew McNulty, Igor Minar, polymer-dev, web-ui

It is unfair to be picking on Polymer here, since as it was pointed out it is an issues which all of the frameworks will be facing. Polymer is a test bed for MDV, and so we are confusing MDV deficiencies with Polymer. 

So let's leave Polymer behind and discuss the actual issue.

From my point of view the issue is that binding frameworks need a way to bind to attributes as well as to properties. The current implementation of MDV only allows binding to attributes. If you wish to bind to properties you have to override the bind method as described here: https://github.com/toolkitchen/mdv/blob/master/docs/node_bind.md

There are two issues with overriding the bind method:
1) the HTML element needs to be aware of MDV to be useful
2) The HTML element may not know how to interpret the path expression.

Lets discuss these two issue further.

Lets say we have <fancy-input> element and an MDV aware framework trying to use it. From a framework point of view there should be no difference between <fancy-input> and <input> or even a <div>. It is all be just elements.



1) The issue of MDV awareness.

We may chose to write:

<input value="{{profile.user.fullName}}>
or
<fancy-input value="{{profile.user.fullName}}>

The issue is that here the value binding is meant to be bound to property not to attribute. In the case of <input> the right thing will happend because <input> is aware of MDV and overwrites the bind method, but <fancy-input> is not aware of MDV and will not overwrite the bind method. 

The corollary to this is that when used with non-MDV framework, there is no way to bind to <input value> since the framework can not take advantage of the .bind method and must directly access the value property.


Summary: Only the elements which are MDV aware will be able to be used in MDV aware framework, because only those elements will know to overwrite the bind method.

The strange part is that it will only be half broken. As long as an element does not need property binding it will work fine in MDV world as soon as we neep property it breaks.

The only reason why <input value> works is because MDV expects that <input> element overwrites the bind method.



2) The issue of expression comprehension

Lets look at <input> closer: <input value="{{profile.user.fullName}}> Since input is overwriting the bind method it needs to know how to interpret the "profile.user.fullName" expression. There are two issues with that:

a) Input now needs to have a rudimentary parser which can navigate the dot expressions
b) The input must make assumptions about the syntax of the expression. This is an issue since the expression comes from the framework domain not input domain. 

While (a) is an issue, I think (b) is a deal breaker. The reason is that when writing templates in a given framework the templates need to be self consistent, and the expressions syntax are governed by the frameworks rules not by the element implementations.

Imagine this scenario:

<template>
  <span>{{a.b.c}}</span>
  <fancy-input-a value="{{a::b::c}}">
  <fancy-input-b value="{{a/b/c}}">
</template>

These three bindings are within a single template, but each binding is following different expression syntax. The reason for this is that it is the element which interprets the syntax not the framework and each element may have different rules.. This is backwards, and it is the root of the issue here. 



Possible solution suggestion:

I think the core idea, that an element is just an element and is unaware of the framework is the right one. For this reason, I think that an element should be able to participate in MDV template without the need to be MDV aware. Elements API should be limited to attributes, properties and events. This implies that it is at template level where we need to resolve the attribute/property issue. Furthermore it should be the template/framework which should be dictating the expression syntax not the element.

1) framework interprets the expressions. Perhaps template.parser = function(expr) { return getterFn_setterFn; }
2) binding syntax differentiates attributes from properties.  {{}} for attributes and [[]] for properties
3) elements don't know they are participating in template


<template>
  <span>{{a.b.c}}</span>
  <fancy-input-a value="[[a.b.c]]">
  <fancy-input-b value="[[a.b.c]]">
</template>

or we could have

<template>
  <span>{{a/b/c}}</span>
  <fancy-input-a value="[[a/b/c]]">
  <fancy-input-b value="[[a/b/c]]">
</template>

if we do

template.parser = function(expr) {  return slashParser(expr); }

Notice that it is the template which decides an the meaning of the expressions syntax and template which governs the binding to attributes/properties. 


I am not saying that this should be the solution, only that this is one way to solve the issue. 

-- misko

Scott Miles

unread,
Jul 3, 2013, 2:44:46 PM7/3/13
to Miško Hevery, Steve Orvell, John Messerly, Justin Fagnani, Matthew McNulty, Igor Minar, polymer-dev, web-ui
Thank you Misko.

Fwiw, this is really along the lines of my own thinking.

Polymer invented a notion of 'published properties', but I kind of wish we hadn't. 

Scott
Reply all
Reply to author
Forward
0 new messages