问题
There're some times when we could need adding a custom element dynamically into a context. Then:
The inserted polymer could receive some properties bound to another property inside the context, so it can change accordingly.
At polymer 0.5 we could use PathObserver to binding a property to a context property for a recently added component. However, I did not find a workaround or equivalent at polymer 1.0.
I have created an example for 0.5 and just the same for 1.0. See below the code of the polymer that it makes the injection. Also you can see the full plunker examples for clarity.
Ej 0.5:
<polymer-element name="main-context">
<template>
<one-element foo="{{foo}}"></one-element>
<div id="dynamic">
</div>
</template>
<script>
Polymer({
domReady: function() {
// injecting component into polymer and binding foo via PathObserver
var el = document.createElement("another-element");
el.bind("foo", new PathObserver(this,"foo"));
this.$.dynamic.appendChild(el);
}
});
</script>
</polymer-element>
Please, see the full plunkr example: http://plnkr.co/edit/2Aj3LcGP1t42xo1eq5V6?p=preview
Ej 1.0:
<dom-module id="main-context">
<template>
<one-element foo="{{foo}}"></one-element>
<div id="dynamic">
</div>
</template>
</dom-module>
<script>
Polymer({
is: "main-context",
ready: function() {
// injecting component into polymer and binding foo via PathObserver
var el = document.createElement("another-element");
// FIXME, there's no a path observer: el.bind("foo", new PathObserver(this,"foo"));
this.$.dynamic.appendChild(el);
}
});
</script>
Please, see the full plunkr example: http://plnkr.co/edit/K463dqEqduNH10AqSzhp?p=preview
Do you know some workaround or equivalent with polymer 1.0?
回答1:
Right now, there is no direct way to do it. You should manually do the double binding by listening to changes in the foo
property of the parent element and listening to the foo-changed
event of the programmatically created element.
<script>
Polymer({
is: "main-context",
properties: {
foo: {
type: String,
observer: 'fooChanged'
}
},
ready: function() {
var self = this;
var el = this.$.el = document.createElement("another-element");
//set the initial value of child's foo property
el.foo = this.foo;
//listen to foo-changed event to sync with parent's foo property
el.addEventListener("foo-changed", function(ev){
self.foo = this.foo;
});
this.$.dynamic.appendChild(el);
},
//sync changes in parent's foo property with child's foo property
fooChanged: function(newValue) {
if (this.$.el) {
this.$.el.foo = newValue;
}
}
});
</script>
You can see a working example here: http://plnkr.co/edit/mZd7BNTvXlqJdJ5xSq0o?p=preview
回答2:
Unfortunately I think it's not possible to do this by a "clean" way. To replace the Path Observer, we have to add link on the "foo" value changes to the dynamic elements. The first step is observe the "foo" property value changes. The second step is replicate the changes to each dynamic elements created.
<dom-module id="main-context">
<template>
<one-element foo="{{foo}}"></one-element>
<div id="dynamic">
</div>
</template>
</dom-module>
<script>
Polymer({
is: "main-context",
// Properties used to make the link between the foo property and the dynamic elements.
properties: {
foo: {
type: String,
observer: 'fooChanged'
},
dynamicElements: {
type: Array,
value: []
}
},
ready: function() {
// injecting component into polymer and binding foo via PathObserver
var el = document.createElement("another-element");
// Keeps a reference to the elements dynamically created
this.dynamicElements.push(el);
this.$.dynamic.appendChild(el);
},
// Propagates the "foo" property value changes
fooChanged: function(newValue) {
this.dynamicElements.forEach(function(el) {
el.foo = newValue;
});
}
});
</script>
See the full Plunkr example: http://plnkr.co/edit/TSqcikNH5bpPk9AQufez
来源:https://stackoverflow.com/questions/30615549/data-binding-in-a-dynamically-inserted-polymer-element