Связывание данных в динамически вставленном полимерном элементе
Иногда возникает необходимость добавить динамический элемент в контекст. Тогда:
-
Вставной полимер может получать некоторые свойства, связанные с другим
свойство внутри контекста, поэтому оно может соответствующим образом изменяться.
-
В полимере 0,5 мы могли бы использовать PathObserver для привязки свойства к
свойство контекста для недавно добавленного компонента. Однако я не
найти обходное решение или эквивалент в отношении полимера 1.0.
Я создал пример для 0.5 и точно так же для 1.0. См. Ниже код полимера, что он делает инъекции. Также для ясности вы можете увидеть полные примеры плунжера.
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>
Пожалуйста, смотрите полный пример plunkr: 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 no a path observer: el.bind("foo", new PathObserver(this,"foo"));
this.$.dynamic.appendChild(el);
}
});
</script>
Пожалуйста, смотрите полный пример plunkr: http://plnkr.co/edit/K463dqEqduNH10AqSzhp?p=preview
Знаете ли вы обходное решение или эквивалент с помощью полимера 1.0?
Ответы
Ответ 1
Прямо сейчас нет прямого способа сделать это. Вы должны вручную выполнить двойное связывание, прослушивая изменения в свойстве foo
родительского элемента и прослушивая событие foo-changed
для программно созданного элемента.
<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 foo property
el.foo = this.foo;
//listen to foo-changed event to sync with parent foo property
el.addEventListener("foo-changed", function(ev){
self.foo = this.foo;
});
this.$.dynamic.appendChild(el);
},
//sync changes in parent foo property with child foo property
fooChanged: function(newValue) {
if (this.$.el) {
this.$.el.foo = newValue;
}
}
});
</script>
Здесь вы можете увидеть рабочий пример: http://plnkr.co/edit/mZd7BNTvXlqJdJ5xSq0o?p=preview
Ответ 2
К сожалению, я думаю, что это невозможно сделать "чистым" способом. Чтобы заменить Path Observer, мы должны добавить ссылку на изменения "foo" для динамических элементов. Первым шагом является изменение значений свойства "foo". Второй шаг - это репликация изменений для каждого созданного динамического элемента.
<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>
См. полный пример Plunkr: http://plnkr.co/edit/TSqcikNH5bpPk9AQufez