8

私が使用している現在の方法は、配列を返すコレクションをフィルタリングし、使用することです

collection.reset(array)

再入力します。ただし、これは元のコレクションを変更するため、コレクションの初期配列状態を追跡する「originalCollectionArray」という配列を追加しました。フィルタリングがアクティブでない場合は、単に使用します

collection.reset(originalCollectionArray)

しかし、実際のコレクションからのモデルの追加と削除を追跡する必要があるため、次のようにしました。

// inside collection
initialize: function(params){
    this.originalCollectionArray = params;
    this.on('add', this.addInOriginal, this);
    this.on('remove', this.removeInOriginal, this);
},
addInOriginal: function(model){
    this.originalCollectionArray.push(model.attributes);
},
removeInOriginal: function(model){
    this.originalTasks = _(this.originalTasks).reject(function(val){
        return val.id == model.get('id');
    });
},
filterBy: function(params){
    this.reset(this.originalCollectionArray, {silent: true});
    var filteredColl = this.filter(function(item){
        // filter code...
    });
    this.reset(filteredColl);
}

並べ替えなど、コレクションの操作に関連する他のトリックを実装しようとすると、これはすぐに面倒になります。率直に言って、私のコードは少しハックに見えます。これを行うエレガントな方法はありますか?

ありがとう

4

2 に答える 2

13

フィルターの状態を反映するメイン コレクションのプロパティとしてコレクションを作成できます。

var C = Backbone.Collection.extend({
    initialize: function (models) {
        this.filtered = new Backbone.Collection(models);
        this.on('add', this.refilter);
        this.on('remove', this.refilter);
    },

    filterBy: function (params){
        var filteredColl = this.filter(function(item){
          // ...
        });

        this.filtered.params = params;
        this.filtered.reset(filteredColl);
    },

    refilter: function() {
        this.filterBy(this.filtered.params);
    }
});

親コレクションは、適用したフィルターに関係なくそのモデルを保持し、フィルター処理されたコレクションにバインドして、いつ変更が発生したかを認識します。add イベントと remove イベントで内部的にバインドすると、フィルターを再適用できます。デモについては、 http://jsfiddle.net/dQr7X/を参照 してください。

于 2012-08-09T15:48:28.207 に答える
1

コードの主な問題は、コレクションではなく生の配列を元の配列として使用していることです。私のコードはあなたのものに近いですが、コレクションのみを使用しているため、追加、削除、フィルターなどのメソッドは元のコードで機能します:

  var OriginalCollection = Backbone.Collection.extend({
  });
  var FilteredCollection = Backbone.Collection.extend({
    initialize: function(originalCol){
        this.originalCol = originalCol;
        this.on('add', this.addInOriginal, this);
        this.on('remove', this.removeInOriginal, this);
    },
    addInOriginal: function(model){
        this.originalCol.add(model);
    },
    removeInOriginal: function(model){
        this.originalCol.remove(model);
    },
    filterBy: function(params){
        var filteredColl = this.originalCol.filter(function(item){
            // filter code...
        });
        this.reset(filteredColl);
    }   
  });
于 2012-08-09T15:50:05.153 に答える