2012-03-21 3 views
0

Я представляю коллекцию моделей, которые связаны с CollectionView, где при визуализации каждый элемент коллекции имеет свой «itemview», который визуализируется.кэшированный вид, теряющий свои события

Когда коллекция сортируется, и listView перерисовывается на основе нового заказа, я создавал совершенно новое представление для каждого элемента, и поскольку я не очищал предыдущие экземпляры представлений, связанных с этой моделью, Я считаю, что зомби оставлены.

Так первоначально рендеринга моей коллекции я сделал бы ...

render : function() { 

    $(this.el).empty(); 
    var content = this.template.tmpl({}); 
    $(this.el).html(content); 
    sortingView.el ='#sorting-container';  
    var els = [];  
    _.each(this.collection.models, function(model){      
     var view = new TB_BB.RequestItemView({model : model}); 
     els.push(view.render().el); 
    }); 
    $('#request-list').append(els); 
    sortingView.render(); 

    return this; 
} 

Поэтому, когда функция визуализации была названа второй/третий раз и т.д., я не прояснил TB_BB.RequestItemView (отсюда и зомби)

Чтобы преодолеть это, я попытался добавить некоторое простое кэширование в виде коллекций, чтобы вместо создания нового элемента itemview, если оно уже было создано, используйте это вместо этого. Мой код

initialize : function(){ 
    _.bindAll(this,"render"); 
    this.collection.bind("add", this.render); 
    this.collection.bind("remove", this.render); 
    this.template = $("#request-list-template"); 
    this.views = {}; 
}, 
events : { 
    "change #sort" : "changesort",  
    "click #add-offer" : "addoffer", 
    "click #alert-button" : "addalert" 
}, 
render : function() { 
    $(this.el).empty(); 
    outerthis = this; 
    var content = this.template.tmpl({}); 
    $(this.el).html(content); 
    sortingView.el ='#sorting-container';  
    var els = [];  
    _.each(this.collection.models, function(model){ 
     var view; 
     if(outerthis.views[model.get('id')]) { 
      view = outerthis.views[model.get('id')]; 
     } else { 
      view = new TB_BB.RequestItemView({model : model}); 
      outerthis.views[model.get('id')] = view; 

     } 
    }); 
    $('#request-list').append(els); 
    sortingView.render(); 
    return this; 
} 

Так это работает так же, как мнения повторно используются - однако то, что я заметил, что если я использую кешированный вид (например, коллекция отсортирована и функции визуализации находит закэшированный view), что все события в подменю перестают работать? почему это?

Также может ли кто-нибудь предложить лучший способ сделать это?

ответ

3

Чтобы связать события снова, вы можете использовать делегаты (http://documentcloud.github.com/backbone/#View-delegateEvents).

+1

Спасибо, вы знаете, почему они потеряют свои события на первом месте? – Xrender

+1

Я бы сказал, что это потому, что их элемент (RequestItemView.el) удален из dom на строке $ (this.el) .empty(). Повторное подключение событий - именно то, для чего предназначен метод delegateEvents. – OlliM

0

Как OlliM упоминается причина в том, что события, которые связаны с элементом DOM, но вместо подмены элемента можно также просто отсоединить их вместо того, чтобы удалить их (открепление сохраняет привязки событий http://api.jquery.com/detach/)

что-то вроде

var $sortContainer = $('#sorting-container'); 
$('li', $sortContainer).detach(); 

А потом просто прикрепить элемент

$cnt.append(view.el); 

Я хотел бы также рассмотреть вопрос об использовании документа фр agment при восстановлении/сортировке списка, а затем добавлении, добавляя это вместо этого.

Смежные вопросы