Backbone.js: событие "смена" коллекции не срабатывает
У меня довольно простая коллекция, но я не могу привязать к ней событие изменения. В консоли 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?
Поскольку это одна из тех вещей, которые трудно отследить, я сомневаюсь, что кто-то знает, что происходит (если это так, здорово!). Итак, я задаю два вопроса:
- Должен ли вышеуказанный код работать так, как ожидалось?
- Если да, то есть ли у вас какие-либо предложения о том, как отслеживать, где это произойдет?
Спасибо
Ответы
Ответ 1
Событие change
запускается только при изменении одной из моделей коллекций. Когда модель добавляется в коллекцию, запускается событие add
.
См. Backbone.js 'Документация по коллекции:
Вы можете связать события "изменения", которые будут уведомлены, когда любая модель в коллекция была изменена, послушайте "добавить" и "удалить", события [...]
Для прослушивания, когда происходит add
, измените свой код как
var c = new AwesomeCollection();
c.bind("add", function(){
console.log('Collection has changed.');
});
c.add({testModel: "Test"});
Ответ 2
Нет, это вызывает только событие "добавить". Если вы сделаете это, оно поднимет событие изменения.
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"});
Ответ 3
Если вы хотите знать, когда что-то значимое было сделано с коллекцией, это те события, которые вы, вероятно, захотите прослушать: change add remove reset
Что касается вашего примера, это может выглядеть как ваш код:
var c = new AwesomeCollection();
c.bind('change add remove reset', function(){
console.log('Collection has changed.');
});
Ответ 4
В большинстве случаев это может быть не обязательно, но вы можете вручную инициировать событие изменения в своем объекте/коллекции:
object.trigger("change");
Ответ 5
Я не нахожу его документированным в любом месте, но событие "все" запускается во всех действиях, включая добавление, удаление и изменение.
var c = new AwesomeCollection();
c.bind("all", function(){
console.log('Something happened');
});
c.add({testModel: "Test"});
Ответ 6
Я надеюсь, что AwesomeCollection - это BackboneCollection.
var AwesomeCollection = new Backbone.Collection();
AwesomeCollection.bind('add', function() {
console.log('new object in the collection');
});
AwesomeCollection.add({something});
Это должно запустить ваше событие. Если нет, в другом месте есть другая проблема.
Изменить: изменить нельзя, чтобы добавить событие, как говорят другие.
Ответ 7
Кроме того, мы не можем сказать из вашего примера, но в коллекции должно быть определено его свойство модели, если вы хотите добавить к нему модели, просто передав объект. В противном случае вы должны передать экземпляр модели для добавления().
Ответ 8
Я столкнулся с той же проблемой, что и ваш, на основе 0.5.3.
Глядя на реализацию 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;
},
Здесь важны две вещи:
this.add(models, {silent: true});
что означает, что у вас не будет никакого события "добавить".
Вторая вещь:
if (!options.silent) this.trigger('reset', this, options);
Это означает, что если вы замените свой код на:
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?
Он должен работать (работал у меня)