分离“骨干”集合(事件问题)



那么,接下来的问题是:我收到大量的价格集合,并且有特定的价格,比如合作伙伴。因此集合包含了用partner_id表示的群。

我对这个集合(使用initialize方法中的collection.filter())进行过滤,为后续视图获得不同的数据"格式"。

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

之后,我将这个新完成的集合传递给管理基本价格列表的视图。

问题本身是我订阅这个新完成的集合的事件,但是在.filter()之后留在那里的模型的事件将它们的事件发射到this.model.get('prices')下的旧集合但是新添加的模型正确地发射它们的事件 (BasePrices集合)。

我不明白为什么会这样。我可以推测有史密斯。与模型对集合(model.collection属性)的参考相关,但为什么当我创建全新的集合时不更新,以及如何解决这个问题?

如果您创建筛选的集合只是为了在视图中使用它,那么使用原始集合并让视图只呈现您想要的项是更好的(也是更正确的)。例如(在视图类中):

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

基本原理是视图表示原始集合。


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

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

问题确实是在引用和克隆 (不是克隆,实际上是)。关键是我们需要将所有内容克隆到新集合。克隆……不复制,不传递(通过引用,我们知道) - 克隆.

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:只是为了保持chain的一致性,这里是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();

最新更新