Ответ 1
Derick Bailey написал подробное сообщение в блоге об этой дилемме, вы можете проверить это здесь: http://lostechies.com/derickbailey/2011/10/11/backbone-js-getting-the-model-for-a-clicked-element/
Мы все знаем, что делать что-то вроде этого плохо:
<ul>
<li>Item</li>
<li>Item</li>
... 500 more list items
</ul>
а затем...
$("ul li").bind("click", function() { ... });
Я просматривал много примеров/руководств по базовым сценариям, и, похоже, это стандартный подход к рендерингу списка элементов, основанный на коллекции моделей.
var ListView = Backbone.View.extend() {
tagName: 'ul',
render: function() {
this.collection.each(function(item) {
var view = new ListItemView({model: item});
$(this.el).append(view.render().el);
});
return this;
}
});
Просмотр элемента списка:
var ListItemView = Backbone.View.extend() {
tagName: 'li',
events: {
'click' : 'log'
}
log : function() {
console.log(this.model.get("title"));
}
render: function() {
$(this.el).html(this.template(this.model.toJSON()));
return this;
}
});
Если я не ошибаюсь, создание экземпляра listView с помощью коллекции с 500 моделями дает мне 500 событий щелчка, по одному для каждой строки. Это плохо?
Я знаю, что Backbone построил делегирование событий для событий с именами:
events : {
'click li' : 'log'
}
Я предполагаю, что могу поместить это в свой ListView, и он создаст только одно событие click для всего списка, но тогда я не смогу получить доступ к данным модели, соответствующим элементу с щелчком.
Какие шаблоны используют базовые разработчики для решения этой типичной проблемы?
Derick Bailey написал подробное сообщение в блоге об этой дилемме, вы можете проверить это здесь: http://lostechies.com/derickbailey/2011/10/11/backbone-js-getting-the-model-for-a-clicked-element/
Следить за просмотром подпунктов из родительского представления. Затем, добавляя subview, добавьте его в хеш, а также добавьте cid к элементу subview. Этот способ имеет указатель на подвью и может выполнять операции над его моделью и т.д.
Я не тестировал этот точный код ниже, так что это может быть неправильно в месте или двух, но я проверил этот общий принцип. Я также пропустил код listitemview.
var ListView = Backbone.View.extend() {
subViews: {},
tagName: 'ul',
events: {
'click li' : 'clickItem'
},
clickItem: function(event){
var id = event.currentTarget.cid;
var subView = this.subViews[id];
},
render: function() {
this.collection.each(function(item) {
var view = new ListItemView({model: item});
this.subViews[view.cid] = view;
subEl = view.render().el;
subEl.cid = view.cid;
$(this.el).append(subEl);
});
return this;
}
});
Вы можете связать экземпляр с таким элементом:
events : {
'click li' : 'log'
},
log: function( e ) {
var elm = e.currentTarget //Same as `this` in normally bound jQuery event
jQuery.data( elm, "viewInstance" ).log( e );
},
Тогда:
var ListItemView = Backbone.View.extend() {
tagName: 'li',
log : function() {
console.log(this.model.get("title");
}
render: function() {
//Associate the element with the instance
$(this.el).html(this.template(this.model.toJSON())).data( "viewInstance", this );
return this;
}
});