2012-06-27 114 views
1

A的每個實例事件有一個創建具有事件他們的OpenOrderViews實例父視圖OpenOrderListView。我想獲得的結果是當OpenOrderViewmarkCompleted按鈕點擊的函數調用來告訴模型來設置屬性骨幹查看觸發了查看

的功能是工作,但它被稱爲父(OpenOrderListView),而不是僅僅在其中點擊事件處理的視圖內的所有OpenOrderViews。我怎樣才能讓這個事件只在觸發的視圖上觸發?

代碼如下

window.OpenOrderListView = Backbone.View.extend({ 
    el: 'table.openOrders tbody', 

    initialize: function() { 
     _.bindAll(this,'render'); 
     this.render(); 
    }, 


    render : function() { 
     var $openOrders 

     var models = this.collection.open(); 

     for (var i = models.length - 1; i >= 0; i--) { 
      console.log('model', models[i]); 
      console.log("this.template", this.template); 
      new OpenOrderView({'model': models[i], 'el': this.el}); 
     }; 

    } 
}); 

window.OpenOrderView = Backbone.View.extend({ 
    initialize: function() { 
     console.log('this', this); 
     _.bindAll(this,'render', 
         'markCompleted', 
         'markInProgress'); 
     this.render(); 
    }, 

    events : { 
     "click .markCompleted": "markCompleted", 
     "click .markInProgress": "markInProgress", 
    }, 

    markCompleted: function(){ 
     console.log(this); 
     this.model.markCompleted(); 
    }, 

    markInProgress: function(){ 
     console.log("markInProgress",this); 
     this.model.markInProgress(); 
     console.log('markInProgress Complete'); 
    }, 

    template : 'template-openOrderView', 

    render : function() { 
     console.log("View Rendered"); 
     $(this.el).append(tmpl(this.template, this.model.toJSON())); 
    } 

    window.Order = Backbone.Model.extend({ 
    url: function(){ 
     return "/api/order/id/"+this.get("id"); 
    }, 

    isCompleted: function(){ 
     return this.get('status') == "completed"; 
    }, 

    isInProgress: function(){ 
     return this.get('status') == "inProgress"; 
    }, 

    isOpen: function(){ 
     return this.get('status') == "open"; 
    }, 

    markCompleted: function(){ 
     this.set({'status':"completed"}); 
     console.log('markCompleted'); 
     return this.save(); 
    }, 

    markInProgress: function(){ 
     this.set({'status':"inProgress"}); 
     console.log('markInProgress'); 
     return this.save(); 
    }, 

    markOpen: function(){ 
     this.set({'status':"open"}); 
     console.log('markOpen'); 
     return this.save(); 
    } 

}); 

}) 

訂單查看模板

<tr class="order"> 
<td class="preview hide_mobile"> 
    <a href="{%=o.api_url%}" title="{%=o.name%}" rel="gallery"><img src="{%=o.thumbnail_url%}"></a> 
</td> 
<td class="name"> 
    <a href="{%=o.api_url%}" title="{%=o.name%}">{%=o.name%}</a> 
</td> 
<td class="description"><span>{%=o.description%}</span></td> 
<td class="hide_mobile date_added"><span>{%=o.date_added%}</span></td> 
<td class="hide_mobile user"><span>{%=o.username%}</span></td> 
<td class="status"> 
    <a class="btn modal-download" target="_blank" href="{%=o.url%}" title="{%=o.name%}" download="{%=o.name%}"> 
     <i class="icon-download"></i> 
     <span>Download</span> 
    </a> 
    <button class="markCancel btn btn-danger" data-type="{%=o.delete_type%}" data-url="{%=o.delete_url%}"> 
     <i class="icon-remove icon-white"></i> 
     <span>Cancel</span> 
    </button> 
    <button class="markInProgress btn btn-primary" data-type="" data-url=""> 
     <i class="icon-repeat icon-white"></i> 
     <span>Mark In Progress</span> 
    </button>  
    <button class="markCompleted btn btn-success" data-type="" data-url=""> 
     <i class="icon-ok icon-white"></i> 
     <span>Mark Completed</span> 
    </button> 
</td> 

回答

6

所有SubViews共享相同的DOM元素table.openOrders tbody。這是該行new OpenOrderView({'model': models[i], 'el': this.el});完成。

所以,當你聲明的事件是這樣的:

events : { 
    "click .markCompleted": "markCompleted" 
} 

正在發生的事情是,符合此table.openOrders tbody .markCompleted所有的DOM元素將與此click事件綁定。

你需要在每個SubView有各自己的this.el DOM元素。

在你的情況,我認爲是更好,如果你的子視圖在空氣中創造他們自己的DOM元素是這樣的:

// code simplified an not tested 
window.OpenOrderView = Backbone.View.extend({ 
    tagName: 'tr', 
    attributes: { class: "order" }, 

    initialize: function(){ 
    // don't render() here 
    }, 

    // ... rest of your code 

    render: function(){ 
    this.$el.html(tmpl(this.template, this.model.toJSON())); 
    return this; 
    } 
}) 

看,現在的SubView渲染本身,既不附加其DOM元素直接到頁,這將是ParentView工作:

// code simplified an not tested 
window.OpenOrderListView = Backbone.View.extend({ 
    render : function() { 
    var $openOrders 

    var models = this.collection.open(); 

    for (var i = models.length - 1; i >= 0; i--) { 
     var openOrderView = new OpenOrderView({'model': models[i]}); 
     this.$el.append(openOrderView.render().el); 
    }; 
}); 

我覺得這是一個很常見的模式。

PD:你必須修改模板移除tr打開/關閉。

+0

太謝謝你了。這幫助我瞭解了引擎蓋下發生了什麼好得多! –

+0

你是最棒的! – stank345