DOMドキュメントフラグメントを使用して大きなテーブルをレンダリングするようにBackboneアプリを変更しました。これにより、行が多い場合にパフォーマンスが大幅に向上します。
残念ながら、これはイベント処理を壊すように思われるため、各行のビューはクリックイベントを受け取らなくなります。これを示すために最小限の例を作成しました。
これを修正するにはどうすればよいですか?
// Javascript
$(window).load(function(){
var Item = Backbone.Model.extend();
var Items = Backbone.Collection.extend({
model: Item,
count: 5,
initialize: function() {
for(i=0; i<this.count; i++){
this.add(new Item({text: i}));
}
}
});
var ItemView = Backbone.View.extend({
tagName: 'tr',
initialize: function(item) {
this.item = item;
},
render: function() {
this.$el.append('<td class="item">' + this.item.get('text') + '</td>');
return this;
},
events: function() {
return { "click .item": function() {
console.log('handling click on item '+this.item.get('text'));
}
};
}
});
var TableBodyView = Backbone.View.extend({
tagName: 'tbody',
render: function() {
if(this.options.useFragment){
this.renderWithFragment();
} else {
this.renderWithoutFragment();
}
return this;
},
renderWithFragment: function() {
var fragment = document.createDocumentFragment();
this.collection.each(function(item){
fragment.appendChild((new ItemView(item)).render().el);
});
this.$el.append(fragment.cloneNode(true));
},
renderWithoutFragment: function() {
self = this;
this.collection.each(function(item){
self.$el.append((new ItemView(item)).render().el);
});
}
});
var items = new Items();
$('#t1').append((new TableBodyView({collection: items, useFragment: false})).render().el);
$('#t2').append((new TableBodyView({collection: items, useFragment: true})).render().el);
});
// HTML
<table id="t1" />
<table id="t2" />
// CSS
table { float: left; margin: 10px; padding: 5px; }
table#t1 { background: green; }
table#t2 { background: red; }