Data-binding between nested polymer elements
data-binding, polymer, shadow-dom, web-component
Solution
Polymer data-binding works by attaching a model to a whole subtree.
You wrote:
<parent-element>
<child-element data2="{{data}}"/>
</parent-element>
this implies a rule that the parentNode provides the binding model. But now imagine you wanted to write:
<parent-element>
<div>
<child-element data2="{{data}}"></child-element>
</div>
</parent-element>
Now you have a problem.
Instead, in Polymer examples, you will notice that the `{{}}` are (almost always) inside of a template. For example, if I define:
<polymer-element name="host-element" attributes="data" noscript>
<template>
<parent-element data1="{{data}}">
<child-element data2="{{data}}"></child-element>
</parent-element>
</template>
</polymer-element>
Now, I have a model context (`host-element`) that I can use to bind things together in the entire subtree described by the template.
Note that I don't need `attributes="data"` for this to work. I added that so host-element exposes `data` and I can do this:
<host-element data="test"></host-element>
http://jsbin.com/IVodePuS/15/edit
Problem
Suppose I have two distinct `polymer-elements` One should be embedded inside the other using the `content` placeholder. Is it possible to do data-binding between these two nested `polymer-elements` ? I tried, but I can't get it to work: http://jsbin.com/IVodePuS/11/ According to http://www.polymer-project.org/articles/communication.html#binding data-binding between `polymer-elements` should work (in those examples they were done inside the `template` tag without using a `content` placeholder). Update: Scott Miles clarified that data-binding only works on the `template` level. However in my case I don't know the exact `template` beforehand but I want to allow the user of my `parent-element` to specify which `child-element` it should contain (provided that there are different `child-elements`. I think this question is related to this one: Using template defined in light dom inside a Polymer element I updated the example below to highlight his: ``` <polymer-element name="parent-element" > <template > <div>Parent data: {{data1}} </div> <content /> </template> <script> Polymer('parent-element', { data1 : '', ready: function() { this.data='parent content'; } }); </script> </polymer-element> <polymer-element name="child-element" attributes="data2"> <template> <div>Parent data: {{data2}} </div> </template> <script> Polymer('child-element', { data2 : '', ready: function() { } }); </script> </polymer-element> <polymer-element name="child2-element" attributes="data2"> <template> <div>Parent data: {{data2}} </div> </template> <script> Polymer('child2-element', { data2 : '', ready: function() { } }); </script> </polymer-element> ``` The user can choose which `child-element` to embed: ``` <parent-element data1 = "test"> <child-element data2="{{data1}}"/> </parent-element> <parent-element data1 ="test" > <child2-element data2="{{data1}}"/> </parent-element> ``` Workaround: The only workaround I found was to add `change watcher` and use `getDistributedNodes()` to get the child element and manually set `data2` to `data`: ``` <polymer-element name="parent-element" > <template > <div>Parent data: {{data}} </div> <content id="content"/> </template> <script> Polymer('parent-element', { data : '', ready: function() { this.data='parent content'; }, dataChanged : function() { contents = this.$.content.getDistributedNodes(); if (contents.length > 0) { contents[0].data2 = this.data; } }, }); </script> </polymer-element> ```