2016-04-28 8 views
0

Polymerを使用してSPAを作成すると、私のバックエンドAPIを表す一般的なカスタムコンポーネントを使用するカスタムコンポーネントが必要となり、データの取得/送信が行われます。 API。また、「キャッシュ」として機能し、表示するデータを保持します。この方法では、この単一要素にアクセスできるすべてのコンポーネントが同じデータを共有します。 <my-api>はなく、一度トップ1の私のすべてのコンポーネントの中で宣言してから受け継がれていないとして、プログラム的JavaScriptでのデータバインディングポリマーのHTMLElementプロパティ

<my-api 
    users="{{users}}" 
    products="{{products}}"> 
</my-api> 

...しかし:

は、だから私は何をしたいのか...これでありますJavaScriptによる階層:

Polymer({ 
    is: 'my-component', 
    properties: { 
    api: { 
     observer: '_onApiChanged', 
     type: HTMLElement 
    }, 
    products: { 
     type: Array 
    }, 
    users: { 
     type: Array 
    } 
    }, 
    _onApiChanged: function(newVal, oldVal) { 
    if (oldVal) 
     oldVal.removeEventListener('users-changed', this._onDataChanged); 

    // Listen for data changes 
    newVal.addEventListener('users-changed', this._onDataChanged); 

    // Forward API object to children 
    this.$.child1.api = newVal; 
    this.$.child2.api = newVal; 
    ... 
    }, 
    _onDataChanged: function() { 
    this.users = this.api.users; // DOESN'T WORK as 'this' === <my-api> 
    this.products = this.api.products; // Plus I'd have to repeat for every array 
    } 
}); 

Polymerはこれを行うための組み込みの方法を提供していますか? 二重中括弧バインディングをプログラムで作成できますか?

+0

API要素を値の代わりに渡す必要があるのはなぜですか? – zacharytamas

+0

@zacharytamas例えば、 'component1'は製品ではなくユーザを聴く必要があるが、サブコンポーネント' subcomponent1'のどちらかに両方が必要なので、 'component1'に' users'プロパティを宣言しなければならないとしましょうそれを 'subcomponent1'に渡すことができます。つまり、ほとんどのコンポーネントですべてのデータ配列を宣言しなければならないということです。新しいデータ型を追加するたびに非常に複雑になりますが、それは非常に冗長です。 – Flawyte

答えて

0

私は他の解決策を使用して終了しました。上位の<my-api>要素を階層の下に手動で渡す代わりに、この共有データにアクセスする必要のある要素は、それ自身の<my-api>を宣言します。

次に、<my-api>要素の宣言で、すべてのインスタンスが同じ配列参照を使用するようにしました。だから私が1つを更新するたびに、それらはすべて更新され、何かをHTML階層に渡す必要はありません。

0

私は恐らくポリマーのバインディングシステムを利用して宣言的にproducts/users配列を渡します。または、my-api要素をすべて共有し、最初に宣言されたものがプライマリであり、将来宣言されるものがレプリカであるような方法で要素を書くことができます。これは、あなたがそれらを必要とする場所に宣言し、Polymerの通常の方法で値にバインドすることを可能にします。

あなたの質問に答えるために、プライベートポリマーAPIを使用せずに、同じ種類のバインディングを簡単にプログラムで簡単にセットアップする方法はありません。

は同じくらいと結合の問題のためにあなたが使用することができたし、の繰り返しを避けるために、ポリマーの内蔵listenunlisten方法:これはあなたがやっている一般的なパターンがどのように考える

Polymer({ 
    is: 'my-component', 
    properties: { 
    api: { 
     observer: '_onApiChanged', 
     type: HTMLElement 
    }, 
    products: { 
     type: Array 
    }, 
    users: { 
     type: Array 
    } 
    }, 
    _onApiChanged: function(newVal, oldVal) { 
    var apiProperties = ['users', 'products']; 

    if (oldVal) { 
     apiProperties.forEach(function(prop) { 
     this.unlisten(oldVal, prop + '-changed', '_onDataChanged'); 
     }); 
    } 

    // Listen for data changes 
    apiProperties.forEach(function(prop) { 
     this.listen(newVal, prop + '-changed', '_onDataChanged'); 
    }); 

    // Forward API object to children 
    this.$.child1.api = newVal; 
    this.$.child2.api = newVal; 
    ... 
    }, 
    _onDataChanged: function() { 
    this.users = this.api.users; // `this` should be the element now 
    this.products = this.api.products; 
    } 
}); 

、あなたは可能性バインディング/バインド解除とAPI要素の転送を抽象化するBehaviorにこれらの要素のいくつかを抽出すると、おそらく多くのメリットがあります。

さらに最適化すると、_onDataChangedに渡されたイベントを見て、変更された値を推測して対応するプロパティを更新できるかどうかを確認することができます。これにより、すべてのプロパティに行を追加する必要がなくなります。

関連する問題