使用Polymer.dart从动态添加的自定义元素内部操纵阴影DOM

时间:2014-02-13 06:46:05

标签: dart dart-polymer polymer web-component

这个最小的聚合物应用程序有一个“浏览器”,可以保存“轨道”。浏览器需要能够在其轨道上调用render。当轨道渲染时,它会向其阴影DOM添加一个新的<p>节点。

现在,render被调用,创建了ParagraphElement并且找到了父“div#insert-here”没有任何问题,但是将新创建的ParagraphElement添加到div的子节点中并不会呈现浏览器。

如果我们在enterView期间更改代码以在 ExampleBrowser的影子dom中插入新的<p>,则<p>会按预期显示在浏览器中。为什么它适用于顶级自定义元素,而不是动态创建的自定义元素?

bugTest.dart

import 'package:polymer/polymer.dart';
import 'dart:html';

@CustomTag('example-browser')
class ExampleBrowser extends PolymerElement {
    @published ExampleTrack track;

    ExampleBrowser.created() : super.created();

    @override
    void enteredView() {
      track = new Element.tag('example-track')
      ..trackName = "Test Track";
    }

    void renderTrack(MouseEvent e) {
      track.render();
    }
}

@CustomTag('example-track')
class ExampleTrack extends PolymerElement {
    @published String trackName;

    ExampleTrack.created() : super.created();

    void render() {
      ParagraphElement testParagraph = new ParagraphElement()
      ..text = "I don't seem to get added to the DOM :(";
      $['insert-here'].children.add(testParagraph);
    }
  }

自定义-elements.html

<script type="application/dart" src="bugTest.dart"></script>

<polymer-element name="example-browser">
  <template>
    <h2>Browser</h2>
    <button on-click="{{renderTrack}}">Render tracks</button>
    <example-track trackName={{track.trackName}}></example-track>
  </template>
</polymer-element>

<polymer-element name="example-track">
  <template>
    <h3>{{trackName}}</h3>
    <div id="insert-here"></div>
  </template>
</polymer-element>

的index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>BugTest</title>
    <link rel="import" href="custom-elements.html">
    <script type="application/dart">export 'package:polymer/init.dart';</script>
    <script src="packages/browser/dart.js"></script>
  </head>
  <body>
    <h1>BugTest</h1>
    <example-browser></example-browser>
  </body>
</html>

1 个答案:

答案 0 :(得分:2)

我认为重复一系列元素无效。

您应该只重复模型数据。

您的代码的作用是

<template repeat="{{track in tracks}}">
  <example-track></example-track> <!-- this element is created tracks.lenght times -->
</template>

您的tracks列表的内容将被完全忽略(除了条目数),因为您没有在标记中引用它。如果您使用@observable List tracks = [1, 2, 3, 4, 5];

,您会得到相同的示例

您应该在render()的{​​{1}}中致电ExampleTrack

这样您就可以从attached()列表中获取数据到您创建的tracks

ExampleTrack

如果要在生成的<template repeat="{{track in tracks}}"> <example-track someattribute="{{track.aField}}"></example-track> </template> 中触发更新,请更改绑定的模型值(ExampleTrack)并让tracks[0].aField = 'someNewValue';ExampleTrack中执行某些操作

你必须小心,void someattributeChanged(old) { /* do something */ }及其中的元素及其字段是可观察的。 在SO上搜索tracks应该有足够的示例。