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});
これらの2つのアクションは、イベントトリガーループに移動this.models[0]します。this.models[3]しかし、iforそのループはただ刻々と過ぎていき、新しいthis.models[3](以前はにあった0)がif (!cids[(model = this.models[i]).cid])再びテストを通過し、2番目の'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正しく実行したい場合は、はるかに複雑になります。