簡體   English   中英

骨干模板內的DOM元素不響應事件

[英]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元素的名稱( divul ,....,默認情況下是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM