从DOM中删除聚合物元素并再次插入后如何更新聚合物元素绑定

亚历克斯·彼得罗巴甫洛夫斯基

假设我们有容器聚合物元素和另一个虚拟聚合物元素。容器聚合物元件具有用于插入其他聚合物的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>

有三个用于插入虚拟聚合物的按钮:

  1. 第一个按钮将第一个模拟聚合物插入容器中。
  2. 第二个按钮也插入第一个虚拟聚合物,并调用prepareElement()该聚合物。
  3. 第三个按钮将第二个虚拟聚合物插入容器

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/

因此,要重现我的问题,请执行以下操作:

  1. 点击“先显示”按钮。确保在内部单击会更改背景颜色并增加计数器。
  2. 在输入字段中输入内容
  3. 点击“显示第二个”
  4. 点击“先显示”。确保第一个聚合物具有与以前相同的状态:背景色,计数器和输入字段文本。
  5. 在第一个聚合物内单击。现在,它不会更改背景颜色和计数器,但是会更改顶部区域的背景颜色。

绑定到可观察的属性不再起作用。但是on-click处理程序有效,您可以在顶部区域的背景颜色更改时看到它。它是通过backgroundColor直接更改element的属性来实现的:

titleElement.style.backgroundColor = color;

所以,我的问题是:在将现有聚合物再次插入DOM后,如何正确更新绑定机制?

有一种方法可以使用“显示先准备好”按钮将其弄脏。prepareElement()在插入容器之前先调用第一个元素。因此,请执行以下操作:

  1. 点击“先显示”按钮。确保在内部单击会更改背景颜色并增加计数器。
  2. 在输入字段中输入内容
  3. 点击“显示第二个”
  4. 点击“显示首先准备的”。您可以看到输入元素为空,但是计数器和背景色是最新的。(如果您在dartium中运行此演示,由于未应用父级样式,白色块也会将其背景颜色更改为父级的背景色)
  5. 在第一个聚合物内单击。现在,它会更改背景颜色和计数器。绑定工作正常,但是我们在输入字段中丢失了文本。

注意:使用“显示第一个准备好的”按钮插入第一个元素后,即使使用“显示第一个准备好的”按钮插入第一个元素后,绑定也可以正常工作。

此处代码https://github.com/petalvlad/dart-style-binding-test

贡特·佐赫鲍尔(GünterZöchbauer)

我自己还没有尝试过,但这似乎是合理的。我希望作者在重用元素时不介意从Detached observables回答他的答案

研究了polymer.js信息位后,我发现有一个cancelUnbindAll函数,在创建元素或将preventDispose属性设置为true时必须调用该函数。

对于可能需要执行此操作的任何人,在Dart实现中,必须在超级调用之后在分离的函数中调用cancelUnbindAll,如下所示:

void detached()
{
    super.detached();
    this.cancelUnbindAll(preventCascade: true);
}

另外,您可以简单地在自定义元素中覆盖preventDispose属性:

bool get preventDispose => true;

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

飞镖聚合物更新聚合物dom元素

来自分类Dev

飞镖聚合物更新聚合物dom元素

来自分类Dev

导入后聚合物更新DOM元素

来自分类Dev

动态插入的聚合物元素中的数据绑定

来自分类Dev

聚合物“ DOM绑定”更新绑定

来自分类Dev

聚合物-更新元素

来自分类Dev

更新聚合物元素模板

来自分类Dev

聚合物-在聚合物元素内部显示元素

来自分类Dev

聚合物-如何创建具有绑定的元素

来自分类Dev

聚合物造型元素

来自分类Dev

转换聚合物元素

来自分类Dev

聚合物中数组元素的绑定子属性

来自分类Dev

如何使用聚合物元素

来自分类Dev

如何动态创建聚合物元素

来自分类Dev

如何构建聚合物元素?

来自分类Dev

聚合物特性不在元素中

来自分类Dev

去除飞镖中的聚合物元素

来自分类Dev

聚合物元素中的getElementById

来自分类Dev

聚合物1.0中的元素特性

来自分类Dev

dom-if模板中的聚合物1.0选择元素

来自分类Dev

聚合物-如何从嵌入元素的页面中触发对嵌入到“聚合物”元素中的元素的操作?

来自分类Dev

聚合物,如何选择条件模板中的元素

来自分类Dev

聚合物元素未从字符串/文本中注册到聚合物中

来自分类Dev

在聚合物元素(聚合物1.2.3)中动态注入共享样式

来自分类Dev

聚合物元素未从字符串/文本中注册到聚合物中

来自分类Dev

如何在聚合物自定义元素中呈现阴影DOM

来自分类Dev

聚合物1.0:带有输入元素的双向绑定

来自分类Dev

聚合物数据与纸质元素的绑定和本地存储

来自分类Dev

聚合物阴影dom元素的基于类的CSS样式