4

「selected」というカスタム属性を持つ「Asset」バックボーンモデルがあります。サーバー側のオブジェクトの一部ではないという意味でのその習慣。ユーザーが現在選択しているアセットのリストを表すために使用します。

var Asset = Backbone.Model.extend({
    defaults: {
        selected: false
    },

    idAttribute: "AssetId"
});

このモデルは、サーバーから変更を取得するために定期的にフェッチするバックボーンコレクションの一部です。

私が抱えている問題は、コレクションをフェッチするたびに、コレクションがリセットを実行しているため(リセットイベントをリッスンすることでわかります)、選択された属性の値がajaxからのデータによって消去されることです。リクエスト。

backbone.jsのドキュメントは、この問題を解決するインテリジェントなマージがあることを示唆しているようです。フェッチメソッドでこれを行っていると思います

 allAssets.fetch({  update: true ,cache: false});

また、モデルに「idAttribute」フィールドを設定して、入ってくるオブジェクトのIDをコレクション内のオブジェクトと比較できるようにしました。

これを解決する方法は、コレクションオブジェクトに独自のParseメソッドを記述することです。

 parse: function (response) {
    // ensure that the value of the "selected" for any of the models
    // is persisted into the model in the new collection
    this.each(function(ass) {
        if (ass.get("selected")) {
            var newSelectedAsset = _.find(response, function(num) { return num.AssetId == ass.get("AssetId"); });
            newSelectedAsset.selected = true;
        }
    });
    return response;
}

これを行うためのより良い方法はありますか?

4

1 に答える 1

1

Collection.update (Backbone 0.9.9 で導入) は確かに既存のモデルをマージしようとしますが、新しいモデルのすべてのセット属性を古いモデルにマージすることによってそうします。Backbone source codeを確認すると、

if (existing || this._byCid[model.cid]) {
    if (options && options.merge && existing) {
        existing.set(model.attributes, options);
        needsSort = sort;
    }
    models.splice(i, 1);
    continue;
}

デフォルトを含むすべての属性が設定されているため、選択した属性が false にリセットされます。selected のデフォルト値を削除すると、意図したとおりに機能します。http://jsfiddle.net/nikoshr/s5ZXN/http://jsfiddle.net/nikoshr/s5ZXN/3/と比較してください。

とはいえ、アプリの状態を保存するためにモデル プロパティに依存するのではなく、別の場所のコントローラーに移動したいと思います。

于 2012-12-21T10:34:55.990 に答える