2013-08-23 59 views
2

我是骨幹新手,我正在嘗試開發一個像Todo一樣的應用程序。骨幹視圖事件不會觸發區別

我有一個主視圖,它是一個列表視圖,它有子視圖。 - 子視圖內容可以雙擊進行編輯,當按下回車鍵時它會被保存。 - 與骨幹github代碼中給出的todo示例非常相似。

var SubView = Backbone.View.extend({ 
    tagName: "li",  
    events: { 
     "dblclick"    : "show_edit_view", 
     "blur .element"   : "close_edit_view", 
     "keypress .element"  : "save_edit_view", 
     "click button.remove" : "remove_question" 
    }, 
    initialize: function(){ 
     this.render();    
     this.listenTo(this.model, "change", this.render); 
    }, 
    render: function(){   
     this.$el.html(_.template($("#sub_view_template").html(),this.model.toJSON())); 
     return this; 
    }, 
    show_edit_view: function() { 
     this.$el.find("div.view").addClass("no_show"); 
     this.$el.find("input").removeClass("no_show"); 
    }, 
    close_edit_view: function(){ 
     this.$el.find("div.view").removeClass("no_show"); 
     this.$el.find("input").addClass("no_show"); 
    }, 
    save_edit_view: function(e){ 
     if (e.keyCode == 13) {    
      this.model.save({name: e.currentTarget.value}); 
      this.close_edit_view(); 
     } 
    } 
}); 

基於這個模板是

<script id="sub_view_template" type="text/x-template"> 
    <div class="view"><%= name %></div> 
    <input class="element no_show" value="<%= name %>" type="text" /> <button class="remove">Remove</button> 
</script> 

這一個正常工作,該模型在視圖更新,更新後的請求被髮送到服務器。

但是,當我更改初始化和save_edit_view函數時,只觸發第一個更改事件而不觸發更改事件。

initialize: function(){ 
    this.render();    
    this.listenTo(this.model, "change", this.render); 
    this.input = this.$("input.element"); 
}, 
save_edit_view: function(e){ 
    if (e.keyCode == 13) {    
     this.model.save({name: $(this.input).val()}); 
     this.close_edit_view(); 
    } 
} 

我在想,問題是什麼?

感謝您的幫助!

+0

多少次,你叫'render'? –

+0

不要在'.initialize()'方法內調用'.render()'函數。渲染應該在視圖之外被調用,並且僅在視圖上實例化並不意味着渲染。 –

+0

@alexanderb因爲subview沒有分配給任何現有的元素 - 我認爲最好在初始化函數中調用render。 - 我想,我可以避免爲它寫一個對象。那是我的意圖。但是,對於綁定到DOM中的現有元素的那些視圖,我總是分別調用渲染。 –

回答

1

問題是你指的只是一個對象。這意味着當您進行作業時:

this.input = this.$('input.element'); // match the current elements

您只從該確切對象獲取值。在第一個change之後,this.input與包含您的新值的對象不同,並且不會與save模型一起使用新值。

演示,可以幫助:

console.log(this.$('input.element') != this.$('input.element')); // true 

這就是爲什麼以下將工作:

save_edit_view: function(e){ 
    if (e.keyCode == 13) {    
    this.model.save({name: this.$('input.element').val()}); 
    this.close_edit_view(); 
    } 
} 
+0

謝謝fbynite!這正是我正在尋找的。當然,它很有效,但是,我想知道,在Backbone的ToDo示例中,他們使用設置this.some_variable的相同方法 - 但在該應用程序中,我無法看到該問題。 –

1

我猜this.$("input.element");是指列表中的第一項。 當你第一次改變模型的價值與它的第一個項目的價值。但第二次它不起作用,因爲第一項的價值仍然相同。 這就是爲什麼你必須從事件獲得輸入值 - e.currentTarget.value

+0

這個。$(「input.element」)是mainview中每個子視圖中的一個元素。我想知道從事件中獲取價值是否是一種好的做法? –

+1

是的,這是一個很好的做法。您在視圖的範圍內綁定事件。當某些事件觸發時,事件中已經有一個元素。所以你不應該再次在DOM中尋找它 - 這是一個多餘的操作。 –

+0

感謝您的信息!這似乎夠邏輯:) –