分隔 `Backbone` collection(事件问题)

Separating a `Backbone` collection (events issue)

所以,接下来的问题是:我收到了大量 collection 的价格,并且有针对特定合作伙伴的价格。因此 collection 包含某种由 partner_id.

表示的组

我过滤这个collection(initialize方法中使用collection.filter()),以获得不同的"format"数据后续浏览量。

var BasePrices = new Collections.ProductPrices( // Creating the same collection type
    this.model.get('prices').filter(function (m) { // But a bit narrowed
        return ~~m.get('partner_id') === 0; // leaving prices without `partner_id`
    })
);

稍后我将这个新完成的 collection 传递给管理基本价格列表的视图。

问题本身是我订阅了这个新完成的collection的事件,但是模型的事件仍然存在.filter() 之后 向位于 this.model.get('prices') 下的旧 collection 发射他们的事件, 但新添加的模型发射他们的事件正确BasePricescollection)。

我不明白为什么会这样。我可以假设有……与collection(model.collection属性)的模型参考有关,但为什么我创建全新的collection时它没有更新以及如何解决问题?

问题确实在引用和克隆中(不是克隆,实际上) .关键是我们需要 clone 一切到新的集合。克隆...不是复制,不是传递(我们知道的引用)- 克隆.

var BasePrices = new Collections.ProductPrices() // Creating the same collection type

_(this.model.get('prices').models) // Implicitly `_.chain`ing
    .filter(function (m) { return ~~m.get('partner_id') === 0; }) // leaving prices without `partner_id`
    .map(function (m) { return m.toJSON(); }) // converting each model to raw object
    .tap(function (a) { c.add(a); }) // adding all models at once
    .value(); // evaluating chain

!非常感谢解决此问题的更优雅的方法。


UPD: 为了保持 chaining 的一致性,这里是 lodash.

的一行
var BasePrices = _(this.model.get('prices').models)
        .filter(function (m) { return ~~m.get('partner_id') === 0; })
        .map(function (m) { return m.toJSON(); })
        // creating collection passing all models in constructor
        .thru(function (a) { return new Collections.ProductPrices(a); })
        .value();

如果您创建过滤后的集合只是为了在视图中使用它,最好(也更正确)使用原始集合并让视图只呈现您想要的项目。例如(在视图 class 内):

render: function() {
    this.model.each(function(m) {
         if(~m.get('partner_id') === 0)
             return;
         /* render m here */
    });
}

理由是视图代表原始集合。


(如果您需要同一集合的多个过滤视图,您可以对所有视图使用一个视图 class 并向其传递一个过滤函数:

initialize: function(filter) {
    this.filter = filter;
}
render: function() {
    this.model.each(function(m) {
         if(!this.filter(m))
             return;
         /* render m here */
    });
}

然后像这样创建视图:new FilteredView(function(m) {return ~~m.get('partner_id') === 0;})