2013-08-23 61 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

感谢您的信息!这似乎够逻辑:) –