过滤Backbone.js集合

时间:2013-01-07 15:32:04

标签: javascript backbone.js

我正在使用几个主干集合,有时我需要根据某些标准访问它们的一部分。

方法1

正如this question中所述,在集合本身使用filter()会返回一个模型数组,而不是另一个集合。这可以在简单的情况下工作,但它会失去集合的方法连接,因为普通的模型数组不会在集合中定义所有方法。

方法2

该问题的答案建议创建一个新的集合,将模型数组传递给构造函数。这有效,但每次调用集合的构造函数都有副作用,因此每次过滤集合时,任何可能在那里定义的事件绑定都会堆叠。

那么基于某些过滤条件创建子集合的正确方法是什么?

我应该使用方法1并依靠方法链来创建更多的过滤方法吗?

我应该使用方法2并避免在集合的构造函数中绑定事件吗?

2 个答案:

答案 0 :(得分:1)

我个人会在集合上创建更多的过滤方法,因为它具有在集合中封装逻辑的额外好处。

您还可以尝试重用现有的集合。我正在考虑这个想法,并得出这样的东西:

var Collection = Backbone.Collection.extend({
  //Takes in n arrays. The first item of each array is the method you want
  //to call and the rest are the arguments to that method. 
  //Sets the collection.models property to the value of each successive filter
  //and returns the result of the last. Revers the collection.models to its original value.
  chainFilters: function(/*args..*/) {
    var models = this.models;
    try {
      filters = _.toArray(arguments);
      _.each(filters, function(filter) {
         this.models = filter[0].apply(this, _.rest(filter));
      }, this);
    } catch(err) {
      this.models = models;
      throw err;
    }

    var filtered = this.models;
    this.models = models;
    return filtered;   
  }
});

用法:

var results = collection.chainFilters(
  [ collection.filter, function(model) { return model.get('name') === 'foo'; } ],
  [ collection.someMethod, 'someargument' ],
  [ collection.someOtherMethod ]
);

Here's a working sample.我知道这有点奇怪。

答案 1 :(得分:0)

这取决于用例。如果您希望这些模型更新视图,那么您可能需要一个新的集合,否则您将无法获得良好的反应模板更新。如果您只是希望模型迭代或操作数据而不用担心数据更新,那么使用数组+ underscore.js。

尝试使用数组,如果你发现自己编写了大量的锅炉板代码,其中的功能已经在一个集合中而不是在underscore.js中,那么就开始使用一个集合。