最干净的方式来摧毁每一个模型在一个集合在 Backbone ?

2jcobegt  于 2022-11-10  发布在  其他
关注(0)|答案(7)|浏览(107)

第一次尝试时我写道

this.collection.each(function(element){
    element.destroy();
});

这是行不通的,因为它类似于Java中的ConcurrentModificationException,每隔一个元素就删除一个。
我尝试在模型上绑定“remove”事件来销毁它自己,就像建议的Destroying a Backbone Model in a Collection in one step?一样,但是如果我在一个属于集合的模型上调用destroy,这将触发2个删除请求。
我查看了下划线doc,没有看到一个向后循环的each()变体,这将解决删除每个元素的问题。
你建议用什么最干净的方式来销毁一系列模型?
谢谢

vwhgwdsa

vwhgwdsa1#

您还可以使用一个好的老式弹出就地销毁:

var model;

while (model = this.collection.first()) {
  model.destroy();
}
zzwlnbp8

zzwlnbp82#

我最近也遇到了这个问题。看起来你解决了它,但我认为更详细的解释可能对其他想知道为什么会发生这种情况的人也会有用。
那么,到底发生了什么呢?
假设我们有一个模型(书籍)的集合(图书馆)。
例如:

console.log(library.models); // [object, object, object, object]

现在,让我们使用您最初的方法检查并删除所有图书:

library.each(function(model) {
  model.destroy();
});

each是一个混合到Backbone集合中的下划线方法。它使用对它的模型的集合引用(library.models)作为这些不同下划线集合方法的默认参数。好的,当然。这听起来很合理。
现在,当model调用destroy时,它也会在集合上触发一个“destroy”事件,这将删除它对模型的引用。

this.models.splice(index, 1);

如果您不熟悉splice,请参阅doc。如果您熟悉,您可能会明白为什么这会有问题。
只是为了证明:

var list = [1,2];
list.splice(0,1); // list is now [2]

这将导致each循环跳过元素,因为它通过models对模型对象的引用正在被动态修改!
现在,如果您使用的JavaScript〈1.6,那么您可能会遇到以下错误:

Uncaught TypeError: Cannot call method 'destroy' of undefined

这是因为在each的下划线实现中,如果本地forEach丢失,它福尔斯到自己的实现。如果在迭代中删除了一个元素,它会抱怨,因为它仍然试图访问不存在的元素。
如果本地forEach确实存在,那么将使用它,而您根本不会收到错误!
为什么?根据doc
如果数组的现有元素被更改或删除,则传递给callback的元素值将是forEach访问它们时的值;不会访问已删除的元素
那么解决方案是什么呢?
如果要从集合中删除模型,请不要使用collection.each。请使用一个允许您处理包含模型引用的新数组的方法。一种方法是使用下划线clone方法。

_.each(_.clone(collection.models), function(model) {
  model.destroy();
});
nr7wwzry

nr7wwzry3#

我说得有点晚了,但我认为这也是一个非常简洁的解决方案:

_.invoke(this.collection.toArray(), 'destroy');
mi7gmzs6

mi7gmzs64#

在Sean安德森的回答上,有一个直接访问 Backbone.js 集合数组的方法,所以你可以这样做。

_.invoke(this.collection.models, 'destroy');

或者只对集合调用reset()而不使用任何参数,则该集合中模型的destroy方法将被触发。

this.collection.reset();

http://backbonejs.org/#Collection-models

jobtbby3

jobtbby35#

这是可行的,有点惊讶,我不能使用下划线。

for (var i = this.collection.length - 1; i >= 0; i--)
    this.collection.at(i).destroy();
guykilcj

guykilcj6#

我更喜欢这种方法,特别是当你需要在每个模型上调用destroy,清除集合,而不是向服务器调用DELETE的时候。
第一个

w8f9ii69

w8f9ii697#

您不需要使用下划线和for循环。

this.collection.slice().forEach(element => element.destroy());

相关问题