分隔 `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 发射他们的事件, 但新添加的模型发射他们的事件正确(到BasePrices
collection)。
我不明白为什么会这样。我可以假设有……与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: 为了保持 chain
ing 的一致性,这里是 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;}
)
所以,接下来的问题是:我收到了大量 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 发射他们的事件, 但新添加的模型发射他们的事件正确(到BasePrices
collection)。
我不明白为什么会这样。我可以假设有……与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: 为了保持 chain
ing 的一致性,这里是 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;}
)