2012-03-06 13 views
6

Bir backbone.js Collection'un ortasına yeni bir model öğesi eklemek ve daha sonra yeni öğeyi doğru konuma eklemek için koleksiyonun View güncelleştirmesini sağlamanın kolay bir yolu var mı?Bir maddeyi bir backbone.js koleksiyonuna ekleme

Listeden öğeler eklemek/silmek için bir denetim üzerinde çalışıyorum. Her liste öğesinin kendi Model ve View vardır ve tüm koleksiyon için de bir View sahibiz.

Her madde görünümü, öğenin modelini klonlayan ve tıklatılan öğenin altındaki dizin konumuna toplayan bir Duplicate düğmesine sahiptir.

Öğeyi koleksiyona eklemek çok kolaydı, ancak koleksiyon görünümünü nasıl güncelleyeceğimi bulmakta zorlanıyorum.

ListView = Backbone.View.extend({ 
    el: '#list-rows', 
    initialize: function() { 
     _.bindAll(this); 
     this.collection = new Items(); 
     this.collection.bind('add', this.addItem); 
     this.render(); 
    }, 
    render: function() { 
     this.collection.each(this.addItems); 
     return this; 
    }, 
    addItem: function (item) { 
     var itemView = new ItemView({ model: item }), 
      rendered = itemView.render().el, 
      index = this.collection.indexOf(item), 
      rows = $('.item-row'); 

     if (rows.length > 1) { 
     $(rows[index - 1]).after(rendered); 
     } else { 
     this.$el.append(rendered); 
     } 
    } 
} 

Bu uygulama çeşit çalışıyor, ama yeni bir öğe eklemek zaman garip hatalar alıyorum: Böyle bir şey çalışıyorum. Eminim bunları çözebilirim ama ...

Kafamda bir ses var, bunu yapmanın daha iyi bir yolu olduğunu söylüyor. Yeni bir ItemView numaranın nereye yerleştirileceğini manuel olarak belirlemek zorundaysa, koleksiyon görünümü koleksiyonun nasıl yeniden oluşturulacağını bilmemeli mi?

Herhangi bir öneriniz var mı?

cevap

4

Yaptığım normal yol, ListView her ItemView işlevini render işlevinde işlemesine izin vermektir. Sonra aynen böyle, render işlevine add olayı bağlamak: Eğer this.collection.add(someModel, {at: index}) diyoruz

ListView = Backbone.View.extend({ 
    el: '#list-rows' 
    , initialize: function() { 
    _.bindAll(this); 
    this.collection = new Items(); 
    this.collection.bind('add', this.render); 
    this.render(); 
    } 
    , render: function() { 
    this.$el.empty(); 
    var self = this; 
    this.collection.each(function(item) { 
     self.$el.append(new ItemView({ model: item }).render().el); 
    }); 
    return this; 
    } 
} 

her şey, görünümü buna göre yeniden işlenecek.

+0

Bunun işe yaraması için 'render 'yönteminin içinde' (.item-row) .remove() 'adlı bir çağrı eklemeliydim, ancak bu iyi bir çözüm. (Aksi takdirde, iadeli ürünler mevcut işlenmiş kalemlerin sonuna eklenmiştir.) Yardım için teşekkürler! –

+0

Oh, bunu yapmak için şunu yapabilirsin. $ El.empty() '' $ el 'toplayarak temizlemeden önce topla :) :) – sntran

+0

Tam olarak koleksiyona şu anda öğe ekliyorum. Yeni eşyayı koleksiyonda doğru yere yerleştiriyor.Yukarıda yaptığım yorumda bir çift yazım hatası olduğunu fark ettim: '$ ('. Item-row ')' i çağırıyorum.sonraki son işlemin oluşturulduğu sırada oluşturulan öğeleri silmek için remove() 'i çağırıyorum. Sadece manzarayı sıfırlıyor. Bunu düşünmeye gel, istediğimi yapabilecek bir “reset” yöntemi var. Bunu çağırmayı ve sonra 'render' demeyi deneyeceğim. –

9

Yeni bir öğe eklerken tüm koleksiyonu yeniden oluşturmanın en iyi çözüm olduğunu düşünmüyorum. Özellikle liste uzunsa, yeni öğeyi doğru yere yerleştirmekten daha yavaştır. Ayrıca, aşağıdaki senaryoyu da düşünebilirsiniz. Koleksiyonlarınızda birkaç öğe yüklersiniz ve ardından n daha fazla öğe eklersiniz (kullanıcı "daha fazla yükle" düğmesini tıklattığında). Bunu yapmak için, seçeneklerden biri olarak add: true'u geçen fetch() yöntemini çağırırsınız. Veriler sunucudan geri alındıkça, 'add' olayı n kez tetiklenir ve listeniz n kez yeniden oluşturulur. esasen sadece :eq() jQuery seçici kullanılarak yerine alıyorum, Yani

var view, prev, prev_index; 
view = new ItemView({ model: new_item }).render().el; 
prev_index = self.model.indexOf(new_item) - 1; 
prev = self.$el.find('li:eq(' + prev_index + ')'); 
if (prev.length > 0) { 
    prev.after(view); 
} else { 
    self.$el.prepend(view); 
} 

:

Aslında sorunuzu kod varyantı kullanıyorum

, burada 'ekle' olay benim geri arama var Yaptığınız tüm öğeleri daha az bellek kullanmalısınız.

+0

Bu harika çalışıyor, ancak listedeki her öğenin yanında rakamlar görüntüliyorum, bu nedenle sayıları senkronize halde tutmak için yeniden oluşturmam gerekiyor. Bunun etrafında bir yol göremiyorum. Bummer .... Buradaki sadeliği seviyorum. – byron

İlgili konular