[英]DOM element inside backbone template doesn't respond to event
我有2個Backbone視圖。 一個視圖(AppView)表示整個集合,當它獲取它時,解析集合並為集合中的每個模型生成單獨的模型視圖。
我遇到的一個問題是,在創建模型視圖時,它們不再響應我的click
事件,這是模型視圖的一種方法。 在模型視圖中,如果我用el
替換tagName
,則事件可以觸發,但是它會針對集合中的每個模型而不是單個模型觸發。
我認為這與在加載時從模板中解開的事件有關,但我無法弄清楚如何綁定,或生成模板而不解開它們。
// INDIVIDUAL ITEMS WITHIN THE VIEW
ModelView = Backbone.View.extend({
// el: '#item-block', // click event shows an action for all 20 models within the collection
tagName: '.item-wrapper', // click event not heard
template: _.template($('#template').html()),
events: {
'click.details': 'fireModel', // .details is a div inside of the template
},
initialize: function () {
// _.bindAll(this, 'render', 'fireModel');
this.render();
},
render: function() {
var holder = $('#item-block');
if(this.model.attributes.caption == null) {
var cloned = _.clone(this.model.get('caption'));
cloned = {};
cloned.text = '';
this.model.set('caption', cloned);
}
holder.append(this.template(this.model.toJSON()));
// this.delegateEvents()
// return this;
},
fireModel: function(e) {
console.log('clicked');
},
});
// COLLECTION GENERATES INDIVIDUAL MODEL VIEW
AppView = Backbone.View.extend({
el: '#social',
events: {
'click #load-more': 'fetchCollection'
},
initialize: function() {
this.collection = new MyCollection();
this.collection.on('sync', this.render, this);
this.collection.fetchData();
},
render: function() {
for (var i = 0; i < this.collection.cache.models.length; i ++) {
modelView = new ModelView({model: this.collection.cache.models[i]});
}
},
fetchCollection: function() {
this.collection.fetchData();
},
});
// CREATE NEW COLLECTION
app = new AppView
這是模板
<section id="social">
<div id="item-block">
</div>
<div id="load-more">Load More</div>
</section>
<script type="text/template" id="template">
<div class="item-wrapper">
<div class="details">
<span class="caption"><%= caption.text %></span>
</div>
<div class="image">
<img src="<%= images.standard_resolution.url %>" data-id="<%= id %>">
</div>
</div>
</script>
<!-- JS LIBS AND BACKBONE SCRIPTS HERE -->
有幾點需要注意:
首先 ,我想提一下Backbone.View
tagName
屬性應該是HTML元素的名稱( div
, ul
,....,默認情況下是div
)。
其次 ,從模型視圖將modelView(childView)附加到appView。 它可以以更好的方式實施。 將該邏輯移動到appView(parentView)。
第三 ,使用Underscore.js的each
方法而不是for
循環。
使用documentFragment緩存childViews並立即追加它,而不是逐個追加(性能優化)。
最后的樣子應該是:
ModelView = Backbone.View.extend({
template: _.template($('#template').html()),
attributes: {
'class': 'item-wrapper'
},
events: {
'click .details': 'fireModel', // .details is a div inside of the template
},
initialize: function () {
this.render();
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
fireModel: function(e) {
console.log('clicked');
},
});
// COLLECTION GENERATES INDIVIDUAL MODEL VIEW
AppView = Backbone.View.extend({
el: '#social',
events: {
'click #load-more': 'fetchCollection'
},
initialize: function() {
this.collection = new MyCollection();
this.collection.on('sync', this.render, this);
this.collection.fetchData();
},
render: function() {
var buffer = document.createDocumentFragment();
this.collection.each(function(model){
if(model.attributes.caption == null) {
// do your checks here
}
var itemView = new ModelView({model: model});
buffer.appendChild(itemView.render().el); // adding it to buffer
});
this.$el.append(buffer); // appending all at once
}
});
// CREATE NEW COLLECTION
app = new AppView();
更新
通過這種方式,任何時間集合的sync
事件都會被觸發,它會將新的itemViews附加到parentView,所以一定要在那里添加檢查。
也許你應該在事件和選擇器之間插入一些空格。
嘗試
'click .details': 'fireModel'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.