假设我们有容器聚合物元件和另一个虚设聚合物元件。容器聚合物元件具有用于插入另一种聚合物的div块。
container_polymer.html
<polymer-element name='container-polymer'>
<template>
<div id="container">
</div>
<button on-click="{{first}}">show first</button>
<button on-click="{{firstPrepared}}">show first prepared</button>
<button on-click="{{second}}">show second</button>
</template>
<script type="application/dart" src="container_polymer.dart">
</script>
</polymer-element>
有三个用于插入虚拟聚合物的按钮:
prepareElement()
对这种聚合物。 container_polymer.dart
import 'package:polymer/polymer.dart';
import 'dart:html';
import 'dummy_polymer.dart';
@CustomTag('container-polymer')
class ContainerPolymer extends PolymerElement {
PolymerElement firstPolymer, secondPolymer, currentPolymer;
Element container;
ContainerPolymer.created() : super.created();
void enteredView() {
super.enteredView();
container = $['container'];
}
void first(Event e, var detail, Node target) {
showFirst(false);
}
void firstPrepared(Event e, var detail, Node target) {
showFirst(true);
}
void showFirst(bool prepare) {
if (firstPolymer == null) {
DummyPolymer dummyPolymer = new Element.tag("dummy-polymer");
dummyPolymer.title = "first";
firstPolymer = dummyPolymer;
}
if (currentPolymer != firstPolymer) {
if (secondPolymer != null) {
secondPolymer.remove();
}
if (prepare) {
firstPolymer.prepareElement();
}
currentPolymer = firstPolymer;
container.children.add(firstPolymer);
}
}
void second(Event e, var detail, Node target){
if (currentPolymer != secondPolymer) {
DummyPolymer dummyPolymer = new Element.tag("dummy-polymer");
dummyPolymer.title = "second";
secondPolymer = dummyPolymer;
if (firstPolymer != null) {
firstPolymer.remove();
}
currentPolymer = secondPolymer;
container.children.add(secondPolymer);
}
}
}
虚拟聚合物具有多种可观察的性质,以测试结合作用。当您在此聚合物内部单击时,它会更改根div的背景颜色,标题div的背景颜色并增加计数器。此外,它还有用于检测聚合物元素状态是否发生变化的输入和用白色背景阻挡以测试父母风格的用法。
dummy_polymer.html
<polymer-element name='dummy-polymer'>
<template>
<div style="width: 500px; height: 300px; background-color: {{color}}" on-click="{{changeColor}}">
<div id="title">
<h1>{{title}}</h1>
<span>Clicks: {{clicks}}</span>
</div>
<input type="text" />
<div class="external">Parent style block: background should be white</div>
</div>
</template>
<script type="application/dart" src="dummy_polymer.dart">
</script>
</polymer-element>
dummy_polymer.dart
import 'package:polymer/polymer.dart';
import 'dart:html';
@CustomTag('dummy-polymer')
class DummyPolymer extends PolymerElement {
@observable String color = "red";
@observable String title;
@observable num clicks = 0;
Element titleElement;
DummyPolymer.created() : super.created() {
var root = getShadowRoot('dummy-polymer');
root.applyAuthorStyles = true;
}
void enteredView() {
super.enteredView();
titleElement = $['title'];
}
void changeColor(Event e, var detail, Node target){
clicks++;
if (color == "red") {
color = "green";
}
else if (color == "green") {
color = "blue";
}
else {
color = "red";
}
titleElement.style.backgroundColor = color;
}
}
此处托管的测试页http://dart-style-binding-test.herokuapp.com/
因此,要重现我的问题,请执行以下操作:
绑定到可观察属性不再起作用。但on-click
处理程序有效,当顶部区域的背景颜色发生变化时,您可以看到它。它是通过直接更改元素的backgroundColor
属性来实现的:
titleElement.style.backgroundColor = color;
所以,我的问题是:如何在现有聚合物再次插入DOM后如何正确更新绑定机制?
有一种方法可以使用“show first prepared”按钮进行弄脏。在插入容器之前,它会在第一个元素上调用prepareElement()
。所以,请做以下事情:
注意:在使用“show first prepared”按钮插入第一个元素后,即使在使用“show first”按钮插入第一个元素之后,绑定也能正常工作。
答案 0 :(得分:4)
我自己没试过,但看起来很合理。 我希望作者不介意从Detached observables when re-using element.
中回答他的答案查看了polymer.js信息位后,我发现有一个cancelUnbindAll函数,必须在创建元素或将preventDispose属性设置为true时调用。
对于可能需要执行相同操作的任何人,在Dart实现中,您必须在超级调用之后在分离函数中调用cancelUnbindAll,如下所示:
void detached()
{
super.detached();
this.cancelUnbindAll(preventCascade: true);
}
或者,您可以简单地覆盖自定义元素中的preventDispose属性:
bool get preventDispose => true;