假设我们有容器聚合物元素和另一个虚拟聚合物元素。容器聚合物元件具有用于插入其他聚合物的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
直接更改element的属性来实现的:
titleElement.style.backgroundColor = color;
所以,我的问题是:在将现有聚合物再次插入DOM后,如何正确更新绑定机制?
有一种方法可以使用“显示先准备好”按钮将其弄脏。它prepareElement()
在插入容器之前先调用第一个元素。因此,请执行以下操作:
注意:使用“显示第一个准备好的”按钮插入第一个元素后,即使使用“显示第一个准备好的”按钮插入第一个元素后,绑定也可以正常工作。
我自己还没有尝试过,但这似乎是合理的。我希望作者在重用元素时不介意从Detached observables回答他的答案。
研究了polymer.js信息位后,我发现有一个cancelUnbindAll函数,在创建元素或将preventDispose属性设置为true时必须调用该函数。
对于可能需要执行此操作的任何人,在Dart实现中,必须在超级调用之后在分离的函数中调用cancelUnbindAll,如下所示:
void detached()
{
super.detached();
this.cancelUnbindAll(preventCascade: true);
}
另外,您可以简单地在自定义元素中覆盖preventDispose属性:
bool get preventDispose => true;
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句