sntran правильно говорит о том, откуда возникла ваша проблема: вы изменяете массив во время его повторения.
Вы начинаете с новой модели с nOrder: null
в начале списка моделей. а>:
splice.apply(this.models, [index, 0].concat(models));
затем add
перебирает модели, запуская 'add'
события по ходу дела. :
for (i = 0, length = this.models.length; i < length; i++) {
if (!cids[(model = this.models[i]).cid]) continue;
options.index = i;
model.trigger('add', model, this, options);
}
Но внутри обратного вызова 'add'
вы изменяете модель:
if(model.get('nOrder') == null)
model.set('nOrder', _.max(collection.pluck('nOrder')) + 1);
а затем отсортировать коллекцию:
collection.sort({silent: true});
Эти два действия перемещают this.models[0]
в this.models[3]
в цикле запуска событий; но i
для этого цикла просто будет продолжать тикать, а новый this.models[3]
(который раньше был 0
) снова пройдет тест if (!cids[(model = this.models[i]).cid])
, и будет ваше второе событие 'add'
.
Вы можете посмотреть эту версию вашей работы со скрипкой, чтобы увидеть, как массив коллекции меняется за вашей спиной:
http://jsfiddle.net/ambiguous/p8Fp4/
Я думаю, что самое простое решение — добавить в вашу коллекцию метод append
, который устанавливает соответствующее значение nOrder
в модели, а затем добавляет его в коллекцию:
append: function(m) {
var nOrder = _.max(this.pluck('nOrder')) + 1;
if(m instanceof Backbone.Model)
m.set({ nOrder: nOrder });
else
m.nOrder = nOrder;
this.add(m);
}
Затем ваш обратный вызов 'add'
может оставить nOrder
в покое и прекратить сортировку коллекции.
Демонстрация: http://jsfiddle.net/ambiguous/JqWVP/
Вы также можете переопределить метод коллекции add
, но это намного сложнее, если вы хотите сделать это правильно.
person
mu is too short
schedule
07.06.2012