2012-08-09 18 views
7

私が使用している現在の方法は、配列を返すコレクションをフィルタリングし、それを再移入しBackbone.js:コレクションをフィルタリングする正しい方法は?

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); 
} 

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

おかげ

+1

はあなただけ( '{:真追加})フェッチ使用していない何らかの理由があります'リセットする代わりに?これはあなたが達成しようとしているようなものです。私はあなたの 'filter'関数が何をしているのかよく分かりませんが、' {data:{...}} 'も渡すことができます。 – bvulaj

+0

正しく理解すれば、originalCollectionArrayとそのイベントを完全に削除し、フィルタ/ソートを行うたびに元のデータをフェッチする必要があります(ソートはフィルタリングされたデータで実行されるので、各ソートもフェッチしてフィルタリングする必要があります)。つまり、ユーザー入力時にフィルターがトリガーされます。あまりにも多くのリソースを無駄にすると思った。私は仮説的にしか話していない。 – chenglou

答えて

11

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

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/を参照してください。

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); 
    } 
    }); 
+0

お返事ありがとうございました。 – chenglou

関連する問題