骨干模板内的DOM元素不响应事件

时间:2014-12-12 17:44:30

标签: javascript backbone.js

我有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 -->

2 个答案:

答案 0 :(得分:1)

有几点需要注意:

首先,我想提及tagName的{​​{1}}属性应该是HTML元素的名称(Backbone.Viewdiv, ....,默认为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'