Javascript Backbone.js:集合的“更改”事件未触发

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8175054/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 04:58:26  来源:igfitidea点击:

Backbone.js: Collection's "change" event isn't firing

javascriptbackbone.js

提问by Thomas

I have a pretty simple collection, but I can't seem to bind to it's change event. In Chrome's console, I'm running:

我有一个非常简单的集合,但我似乎无法绑定到它的更改事件。在 Chrome 的控制台中,我正在运行:

var c = new AwesomeCollection();
c.bind("change", function(){
  console.log('Collection has changed.');
});

c.add({testModel: "Test"}); // Shouldn't this trigger the above log statement?

Since this is one of those things that can be difficult to track down, I doubt anybody knows off the top of their head what's going on (if so, great!). So, I'm asking two questions:

由于这是难以追踪的事情之一,我怀疑有人完全不知道发生了什么(如果是这样,那就太好了!)。所以,我问两个问题:

  1. Should the above code work as anticipated?
  2. If so, do you have any suggestions on how to track down where this would fail?
  1. 上面的代码应该按预期工作吗?
  2. 如果是这样,您对如何追踪这会失败的地方有什么建议吗?

Thanks

谢谢

回答by soldier.moth

The changeevent is only fired when one of the collections' models are modified. When a model is added to the collection the addevent is fired.
See Backbone.js' Collection Documentation:

change仅当修改集合的模型之一时才会触发该事件。当模型被添加到集合中时,add事件被触发。
请参阅 Backbone.js 的集合文档

You can to bind "change" events to be notified when any model in the collection has been modified, listen for "add" and "remove" events[...]

您可以绑定“更改”事件以在集合中的任何模型被修改时收到通知,侦听“添加”和“删除”事件[...]

To listen for when an addoccurs modify your code to be

要侦听何时add发生,请将您的代码修改为

var c = new AwesomeCollection();
c.bind("add", function(){
  console.log('Collection has changed.');
});

c.add({testModel: "Test"}); 

回答by timDunham

No, that only raises the "add" event. It will raise the change event if you do this:

不,那只会引发“添加”事件。如果您这样做,它将引发更改事件:

var c = new AwesomeCollection();
c.bind("change", function() {
  console.log('Collection has changed.');
});

var model = new Backbone.Model({testModel: "Test"});
c.add(model);
model.set({testModel: "ChangedTest"});

回答by Chris Dutrow

If you want to know when something of significance has been done with a collection, these are the events you probably want to listen to: change add remove reset

如果您想知道某个集合何时完成了重要的事情,这些是您可能想听的事件: change add remove reset

With respect to your example, this is what your code might look like:

关于您的示例,您的代码可能如下所示:

var c = new AwesomeCollection();
c.bind('change add remove reset', function(){
    console.log('Collection has changed.');
});

回答by Chicowitz

It may not be necessary in most cases, but you can manually trigger a change event on your object/collection:

大多数情况下可能没有必要,但您可以手动触发对象/集合上的更改事件:

object.trigger("change");

回答by Gaurav Gupta

I don't find it documented anywhere but the "all" event fires on all actions, including add, remove and change.

我没有发现它在任何地方都有记录,但是“所有”事件会触发所有操作,包括添加、删除和更改。

var c = new AwesomeCollection();
c.bind("all", function(){
  console.log('Something happened');
});

c.add({testModel: "Test"}); 

回答by maxl0rd

Also, we cannot tell from your example, but a Collection must have its model property defined if you want to add models to it by simply passing an object. Otherwise, you must pass a model instance to add().

此外,我们无法从您的示例中看出,但是如果您想通过简单地传递一个对象来向 Collection 添加模型,则必须定义它的模型属性。否则,您必须将模型实例传递给 add()。

回答by Frédéric

I faced the same issue as yours on backbone 0.5.3.

我在主干 0.5.3 上遇到了和你一样的问题。

Looking at Backbone.Collection.reset() implementation (which is called after a fetch() if you don't provide any "add" optional property), line 503 to 511 :

查看 Backbone.Collection.reset() 实现(如果您不提供任何“添加”可选属性,则在 fetch() 之后调用),第 503 至 511 行:

// When you have more items than you want to add or remove individually,
// you can reset the entire set with a new list of models, without firing
// any `added` or `removed` events. Fires `reset` when finished.
reset : function(models, options) {
  models  || (models = []);
  options || (options = {});
  this.each(this._removeReference);
  this._reset();
  this.add(models, {silent: true});
  if (!options.silent) this.trigger('reset', this, options);
  return this;
},

2 things are important here :

这里有两件事很重要:

  this.add(models, {silent: true});

which means you won't have any "add" event triggered.

这意味着您不会触发任何“添加”事件。

Second thing is the :

第二件事是:

  if (!options.silent) this.trigger('reset', this, options);

Meaning that if you replace your code with :

这意味着如果您将代码替换为:

var c = new AwesomeCollection();
c.bind("reset", function(){
  console.log('Collection has changed.');
}

c.add({testModel: "Test"}); // Shouldn't this trigger the above log statement?

It should work (worked for me)

它应该工作(为我工作)

回答by malletjo

I hope AwesomeCollection is a BackboneCollection.

我希望 AwesomeCollection 是一个 BackboneCollection。

var AwesomeCollection = new Backbone.Collection();

AwesomeCollection.bind('add', function() {
    console.log('new object in the collection');
});

AwesomeCollection.add({something});

This should fire your event. If not, there is another problem somewhere else.

这应该会触发您的事件。如果没有,则在其他地方还有另一个问题。

Edit: change can't be fired on add event like others said.

编辑:不能像其他人所说的那样在添加事件上触发更改。