简体   繁体   中英

Data binding attributes of dynamically created polymer elements

If I want to bind the attributes of two polymer elements together then I can use data binding in a template and do the following:

<!-- Publish .items so others can use it for attribute binding. -->
<polymer-element name="td-model" attributes="items">
  <script>
    Polymer('td-model', {
      ready: function() {
        this.items = [1, 2, 3];
      }
    });
  </script>
</polymer-element>

<polymer-element name="my-app">
  <template>
    <td-model items="{{list}}"></td-model>
    <polymer-localstorage name="myapplist" value="{{list}}"></polymer-localstorage>
  </template>
  <script>
    Polymer('my-app', {
      ready: function() {
        // Initialize the instance's "list" property to empty array.
        this.list = this.list || [];
      }
    });
  </script>
</polymer-element>

From http://www.polymer-project.org/articles/communication.html#binding

However, if I'm creating an element (let's call it) <my-childelement> dynamically using document.createElement() inside of another element <my-parentelement> then how can I synchronise changes made to an attribute of my-childelement with my-parent element?

One option is to emit events from the child element and subscribe to them in the parent, but this is tedious when I have quite a lot of attributes that I want to keep in sync and I then have to manage adding/removing listeners whenever the childelement is replaced with a different child element.

Node.bind() looks like it might be after but I'm not sure if I'm misunderstanding it's purpose.

I'm hoping to be able to do something along the lines of this:

<polymer-element name="my-parentelement" attributes="shape">
  <script>
    Polymer('my-parentelement', {
      shape: square,
      ready: function() {
        var child = document.createElement('my-childelement');
        this.bind('shape', new PathObserver(child, 'shape');

        // Now this.shape will be kept in sync with child.shape, e.g.
        child.shape = 'triangle';
        this.shape == child.shape; // evaluates to true
      }
    });
  </script>
</polymer-element>

There are various ways one can handle this kind of polymorphism, but in this case, it seems like simple template conditionals are a good fit. IOW, something like this

  <template>
    <template if="{{kind == 'vimeo'}}">
      Vimeo: {{name}}
    </template>
    <template if="{{kind == 'soundcloud'}}">
      Soundcloud <b>{{name}}</b>
    </template>
    ...

Running version here: http://codepen.io/sjmiles/pen/FkacJ?editors=100

This works for me to dynamically add a custom element and then bind it. I also have an example of dynamically importing the element, then loading and then binding it.

Runnable code here: https://github.com/semateos/polymer-lazy-load

demo-app.html:

<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="lazy-test.html">

<polymer-element name="demo-app" attributes="session">
  <template>

    <input type="text" value="{{session.id}}">

    <button on-tap="{{buttonClick}}">Test</button>

    <div id="holder"></div>

  </template>
  <script>
    Polymer({

      buttonClick: function(e){

        //create the polymer element
        var child = document.createElement('lazy-test');

        //bind the session value to the parent
        child.bind('session', new PathObserver(this, 'session'));

        //attach it to the parent
        this.$.holder.appendChild(child);
      },

      created: function() {

        //set the initial value
        this.session = {id: '123'};
      }
    });
  </script>
</polymer-element>

lazy-test.html:

<link rel="import" href="/bower_components/polymer/polymer.html">

<polymer-element name="lazy-test" attributes="session">
  <template>

    <h1>Lazy Child: {{session.id}}</h1>

    <input type="text" value="{{session.id}}">

  </template>
  <script>
    Polymer({

      created: function() {

        // hint that session is an object
        this.session = {};
      }
    });
  </script>
</polymer-element>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM