9

rivets.js初心者はこちら。動的に変化するアイテム(store.ActiveItem)にバインドしたい。次の方法を試しましたが、store.ActiveItemは設定されていますが、store.ActiveItem。(任意のプロパティ)は常に未定義です。1つのレベルよりも深くバインドする標準的な方法はありますか?

<div id="editItemDialog" data-modal="store.ActiveItem < .ActiveItem">
    <a data-on-click="store:ClearActiveItem" href="#">close - works</a>
    <div>
        <div>
        <label>name:</label><input data-value="store.ActiveItem.Name < .ActiveItem"/>
        </div>
        <div>
        <label>price:</label><input data-value="store.ActiveItem.Price < .ActiveItem"/>
        </div>
        <div>
        <label>description:</label><textarea data-value="store.ActiveItem.Description < .ActiveItem"></textarea>
        </div>
    </div>
</div>
4

1 に答える 1

23

バインディングがどのように機能するかは、主に使用しているリベットアダプターによって決まりますが、モデルは重い物を持ち上げることもできます。

オプション1:スマートモデル

Backbone.jsを使用している場合は、まだ開発中ですが、ネストされた属性(例)のパス構文をサポートするbackbone-deep-modelを確認できます。store.get('ActiveItem.Price')それがあなたのニーズを完全に満たしていない場合は、 Backboneプラグインと拡張機能のwikiに他のネストされたモデルタイプのオプションがあります。

オプション2:スマートアダプター

それでも問題が解決しない場合は、Rivetsアダプターを拡張してパス構文を処理できます。http://jsfiddle.net/zKHYz/2/で、次の単純なアダプターを使用してこれを行う方法の簡単な例をまとめました。

rivets.configure({
    adapter: {
        subscribe: function(obj, keypath, callback) { /* Subscribe here */ },
        unsubscribe: function(obj, keypath, callback) { /* Unsubscribe here */ },
        read: function(obj, keypath) {
            var index = keypath.indexOf('.');
            if (index > -1) {
                var pathA = keypath.slice(0, index);
                var pathB = keypath.slice(index + 1);
                return obj[pathA][pathB];
            } else {
                return obj[keypath];
            }
        },
        publish: function(obj, keypath, value) {
            var index = keypath.indexOf('.');
            if (index > -1) {
                var pathA = keypath.slice(0, index);
                var pathB = keypath.slice(index + 1);
                return obj[pathA][pathB] = value;
            } else {
                return obj[keypath] = value;
            }
        }
    }
});

オプション3:ダーティハック

バージョン0.3.2以降、Rivetsは反復バインディングをサポートしています。配列を返すRivetsフォーマッターを作成することで、プロパティを「反復」できます。この実用的な例については、http://jsfiddle.net/mhsXG/3/をご覧ください。

rivets.formatters.toArray = function(value) {
    return [value];
};

<div data-each-item="store.ActiveItem | toArray < store.ActiveItem"">
    <label>name:</label><input data-value="item.Name < store.ActiveItem"/>
    ...
</div>

ここで計算されたプロパティ構文が必要かどうかはわかりません。何が機能するかを確認するには、モデルでこれをテストする必要があります。

オプション4:1レベルより深くバインドしない(推奨)

1つのレベルよりも深くバインドする必要がある場合は、デザインを改善できることを示している可能性があります。

あなたの例では、ストアのItemCollectionにアイテムのリストがあります。単一のアイテムをストアのActiveItemプロパティに割り当て、イベントをどこにでも設定してリンクを試み、ストアの下のActiveItemのプロパティにバインドできる必要がありますが、ActiveItem自体が変更されるたびに更新されます。 、など。

これを行うためのより良い方法は、モデルごとのビューアプローチを使用することです。この例では、ストアモデル、ItemCollection、およびアイテムモデルを単一のビューで処理しようとしています。代わりに、親のストアビュー、ItemCollectionのサブビューを作成し、必要に応じてその下にアイテムビューを生成できます。このように、ビューの構築とデバッグが容易になり、モデルデザイン全体との緊密な結合が少なくなり、アプリケーション全体でより簡単に再利用できます。この例では、状態を維持するためにストアのActiveItemプロパティが不要になるため、モデルの設計も簡素化されます。アイテムビューを選択したアイテムモデルにバインドするだけで、すべてがアイテムビューで解放されます。

Backbone.jsを使用している場合は、開始点としてBackbone.Viewを確認してください。オンラインには多くの例がありますが、特にネストされたビューがある場合は、状況が多少複雑になる可能性があることを最初に認めます。Backbone.LayoutManagerと、それがこの複雑さをどのように軽減するかについて良いことを聞いたことがありますが、まだ自分で使用する機会はありません。

http://jsfiddle.net/EAvXT/8/で生成されたアイテムビューを使用するように最新の例を変更し、それに応じてActiveItemプロパティを廃止しました。StoreビューをItemCollectionビューから分割していませんが、にバインドする必要がないように、モデルをRivetsに個別に渡すことに注意してくださいstore.Items.models。繰り返しになりますが、これはかなり単純な例であり、ビューが削除されたときにリベットのバインドを解除するなど、ビューのライフサイクル全体を処理しません。

于 2012-10-18T22:40:35.540 に答える