我有2个Backbone视图。一个视图(AppView)表示整个集合,当它获取它时,解析集合并为集合中的每个模型生成单独的模型视图。
我遇到的一个问题是,在创建模型视图时,它们不再响应我的click
事件,这是模型视图的一种方法。在模型视图中,如果我将tagName
替换为el
,则事件可以触发,但是它会针对集合中的每个模型而不是单个模型触发。
我认为这与在加载时从模板中解开的事件有关,但我无法弄清楚如何绑定,或生成模板而不解开它们。
// 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 -->
答案 0 :(得分:1)
有几点需要注意:
首先,我想提及tagName
的{{1}}属性应该是HTML元素的名称(Backbone.View
,div
, ....,默认为ul
)。
第二次,您将modelView(childView)从模型视图附加到appView。它可以更好地实现 方式。将该逻辑移动到appView(parentView)。
第三次,使用Underscore.js的div
方法代替each
循环。
使用documentFragment缓存childViews并立即追加它,而不是逐个追加(性能优化)。
最后的样子应该是:
for
<强>更新强>
通过这种方式,任何时间集合的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();
事件被触发,它会将新的itemViews附加到parentView,所以一定要在那里添加检查。
答案 1 :(得分:0)
也许你应该在事件和选择器之间插入一些空格。
试
'click .details': 'fireModel'