4

对于以下代码,add视图中绑定的事件会触发两次(如果一次向集合中添加更多元素,则会触发更多)。

http://jsfiddle.net/radu/GnG66/

App = window.App || {};

var Model = Backbone.Model.extend();
var Collection = Backbone.Collection.extend();
App.collection = new Collection({ model: Model });

var View = Backbone.View.extend({
    events: {
        'click': function() {
            console.log('click');
            App.collection.add([{
                foo: 'foo'
            }, {
                bar: 'bar'
            }]);
        }
    },
    initialize: function() {
        App.collection.on('add', function() {
            console.log('Something has been added to the collection')
        }, this);
    }
});

$(function() {
    App.view = new View({ el: '#test' });
});​

如果您不向集合中添加数组,而是将几个对象作为参数传递(基本上只是删除方括号),则该事件只会触发一次。

这是设计使然,有没有办法在不{ silent : true }作为选项传递的情况下覆盖此行为?

4

2 回答 2

3

add每个添加的模型都会触发一次该事件。

Collection.add可以采用一系列模型,或单个模型和一些选项。

在上面的示例中,您传递了一个包含两个模型的数组。由于add每个添加的模型都会触发一次事件,因此它会触发两次。

当您传入多个对象时,Backbone 认为第一个对象是模型,第二个对象是选项哈希。这意味着只添加了一个模型,因此它会触发add一次事件。

于 2012-08-15T22:51:40.757 回答
1

很抱歉从死里复活这个问题,但我也遇到了这个问题,想发布我是如何解决的。'add'对我来说多次触发的问题是因为我认为我有一个复杂的渲染函数正在监听'add'. 这导致了严重的性能问题。

我通过使用主干的方便collection.clone()方法创建一个临时集合来解决它,将新模型添加到其中,然后使用临时集合的models属性重置原始集合。代码如下所示:

// Create a temporary copy of searchResults
var temp = App.searchResults.clone();

// Add the new results
temp.add(newResults.models);

// Copy the new data over the old data
App.searchResults.reset(temp.models);

// Added this since reset triggers 'reset' and my view is listening for 'change add remove'
this.get('filtered_flights').trigger('change');

这只会引发一个'change'事件而不是几个'add'事件。

于 2013-05-31T17:48:39.363 回答