web-dev-qa-db-ja.com

動的に挿入されたpolymer elementのデータバインディング

カスタム要素をコンテキストに動的に追加する必要がある場合があります。次に:

  • 挿入されたpolymerは、コンテキスト内の別のプロパティにバインドされたいくつかのプロパティを受け取る可能性があるため、それに応じて変更できます。

  • polymer 0.5では、PathObserverを使用して、最近追加されたコンポーネントのコンテキストプロパティにプロパティをバインドできます。ただし、polymer = 1.0。

0.5の例を作成しましたが、1.0の例も同じです。以下のpolymerのコードを参照して、注入を行います。また、明確にするために、完全なプランカーの例を参照してください。

Ej 0.5:

<polymer-element name="main-context">
  <template>
    <one-element foo="{{foo}}"></one-element>
    <div id="dynamic">
    </div>
  </template>
  <script>
    Polymer({
      domReady: function() {
        // injecting component into polymer and binding foo via PathObserver
        var el = document.createElement("another-element");
        el.bind("foo", new PathObserver(this,"foo"));
        this.$.dynamic.appendChild(el);
      }
    });
  </script>
</polymer-element>

完全なplunkrの例を参照してください: http://plnkr.co/edit/2Aj3LcGP1t42xo1eq5V6?p=preview

Ej 1.0:

<dom-module id="main-context">
  <template>
    <one-element foo="{{foo}}"></one-element>
    <div id="dynamic">
    </div>
  </template>
</dom-module>
<script>
  Polymer({
    is: "main-context",
    ready: function() {
      // injecting component into polymer and binding foo via PathObserver
      var el = document.createElement("another-element");
      // FIXME, there's no a path observer: el.bind("foo", new PathObserver(this,"foo"));
      this.$.dynamic.appendChild(el);
    }
  });
</script>

Plunkrの完全な例を参照してください: http://plnkr.co/edit/K463dqEqduNH10AqSzhp?p=preview

polymer 1.0の回避策または同等のものを知っていますか?

14
recluising

現在、それを行う直接的な方法はありません。親要素のfooプロパティの変更をリッスンし、プログラムで作成された要素のfoo-changedイベントをリッスンして、手動でダブルバインディングを実行する必要があります。

<script>   
Polymer({
  is: "main-context",
  properties: {
    foo: {
      type: String,
      observer: 'fooChanged'
    }
  },
  ready: function() {
    var self = this;
    var el = this.$.el = document.createElement("another-element");

    //set the initial value of child's foo property
    el.foo = this.foo;
    //listen to foo-changed event to sync with parent's foo property
    el.addEventListener("foo-changed", function(ev){
      self.foo = this.foo;
    });

    this.$.dynamic.appendChild(el);
  },
  //sync changes in parent's foo property with child's foo property
  fooChanged: function(newValue) {
    if (this.$.el) {
      this.$.el.foo = newValue;
    }
  }
});
</script>

ここで実際の例を見ることができます: http://plnkr.co/edit/mZd7BNTvXlqJdJ5xSq0o?p=preview

残念ながら、これを「クリーンな」方法で行うことは不可能だと思います。パスオブザーバーを置き換えるには、「foo」値の変更に関するリンクを動的要素に追加する必要があります。最初のステップは、「foo」プロパティ値の変化を観察することです。 2番目のステップは、作成された各動的要素に変更を複製することです。

<dom-module id="main-context">
  <template>
    <one-element foo="{{foo}}"></one-element>
    <div id="dynamic">
    </div>
  </template>
</dom-module>
<script>
Polymer({
  is: "main-context",
  // Properties used to make the link between the foo property and the dynamic elements.
  properties: {
    foo: {
      type: String,
      observer: 'fooChanged'
    },
    dynamicElements: {
      type: Array,
      value: []
    }
  },
  ready: function() {
    // injecting component into polymer and binding foo via PathObserver
    var el = document.createElement("another-element");
    // Keeps a reference to the elements dynamically created
    this.dynamicElements.Push(el);
    this.$.dynamic.appendChild(el);
  },
  // Propagates the "foo" property value changes
  fooChanged: function(newValue) {
    this.dynamicElements.forEach(function(el) {
      el.foo = newValue;
    });
  }
});
</script>

Plunkrの完全な例を参照してください: http://plnkr.co/edit/TSqcikNH5bpPk9AQufez

7
Mason