Using Polymer.dart to manipulate the shadow DOM from inside a dynamically added custom element

StackOverflow https://stackoverflow.com/questions/21747093

Вопрос

This minimal polymer app has a 'browser' that holds 'tracks'. The browser needs to be able to call render on its tracks. When a track renders, it adds a new <p> node to its shadow DOM.

As it stands, render is called, the ParagraphElement is created and the parent "div#insert-here" is found without any trouble, but adding the newly created ParagraphElement to the div's children doesn't render in the browser.

If we change the code to insert a new <p> into the ExampleBrowser's shadow dom during enteredView, the <p> appears in the browser as expected. Why would it work for the top-level custom element, but not the dynamically created custom element?

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);
    }
  }

custom-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>
Это было полезно?

Решение

I don't think repeating over a list of elements is working.

You should only repeat over model data.

What your code does, is

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

the content of your tracks list is ignored completely (beside the number of entries) because you don't refer to it in your markup. You would get the same example if you use @observable List tracks = [1, 2, 3, 4, 5];

You should call render() in ExampleTrack's attached() instead.

This way you get data from your tracks list to your created ExampleTrack

<template repeat="{{track in tracks}}">
  <example-track someattribute="{{track.aField}}"></example-track> 
</template>

If you want to trigger updates in your generated ExampleTracks, change the bound model value (tracks[0].aField = 'someNewValue';) and let the ExampleTrack do something in void someattributeChanged(old) { /* do something */ }

You have to take care, that tracks and the elements inside it and their fields are observable. Search for [dart] observable on SO there should be enough examples.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top