Backbone.View:delegateEvents不会再次将事件绑定到子视图 [英] Backbone.View: delegateEvents not re-binding events to subview
问题描述
我有这个问题分解成尽可能小的例子(即,它只是为说明问题,而不是一定重新present一个真实世界的场景)。
I have broken down this issue into the smallest example possible (i.e., it's only to demonstrate the problem, not to necessarily represent a real-world scenario).
让我们说我有一个包含子视图(子视图在这里)父视图(的MainView在这里)。如果在任何时候,我需要重新呈现父视图(这由此重新呈现子视图),我,失去了事件绑定在子视图,尽管调用 delegateEvents
。
Let's say I have a parent view ("MainView" here) that contains a child view ("SubView" here). If, at any point, I need to re-render the parent view (which thereby re-renders the child view), I am losing the event bindings in the child view, despite calling delegateEvents
.
一个的jsfiddle可以在这里找到: http://jsfiddle.net/ya87u/1/
A jsfiddle can be found here: http://jsfiddle.net/ya87u/1/
下面是充满了code:
Here is the code in full:
var MainView = Backbone.View.extend({
tagName : "div",
initialize : function() {
this.subView = new SubView();
},
render : function() {
this.$el.html(this.subView.render().$el); // .html() breaks binds
this.subView.delegateEvents(); // this re-establishes them
return this;
}
});
var SubView = Backbone.View.extend({
tagName : "div",
events : {
"click .button1" : "onButtonPress"
},
onButtonPress : function() {
alert("Button pressed");
},
render : function() {
var html = "<button class='button1'>Button1</button>";
this.$el.html(html);
return this;
}
});
var v = new MainView();
$("#area1").html(v.render().$el); // binds work fine
// do some work... then re-render...
$("#area1").html(v.render().$el); // breaks event binds
我不明白为什么会这样。任何投入将大大AP preciated。
I do not understand why this is happening. Any input would be greatly appreciated.
推荐答案
要preserve绑定,你可以做三件事情。
To preserve the bindings you could do three things.
使用 $。追加
将让您的绑定完好无损,也照顾你不会丢失任何同级的内容。
Using $.append
will keep your bindings intact and also take care that you don't lose any sibling content.
在您的code你重新渲染你的看法,也重新重视它的内容。这是没有必要的。简单地调用 v.render()
将实现同样的视觉效果,但保留您的绑定不变。
In your code you re-render your view and also re-attach it's content. This is not necessary. Simply calling v.render()
will achieve the same visual result but keep your bindings intact.
var v = new MainView();
$("#area1").html(v.render().$el); // binds work fine
// do some work... then re-render…
v.render(); // keeps event binds
$("#area1").append(v.render().$el); // works too
调用$的.html之前使用$ .empty()()
按照 jQuery的文档$的.html(htmlString)
如果您把这些DOM元素引用,并需要他们保持不变,使用.empty()。HTML(串),而不是html的(串),这样的元素从文档中删除之前,新的字符串分配给元素
If you are keeping references to these DOM elements and need them to be unchanged, use .empty().html( string ) instead of .html(string) so that the elements are removed from the document before the new string is assigned to the element.
最重要的部分是,$ html的期望一个HTML字符串,而不是元素也解除绑定子节点上的任何事件处理present。我可以解释这种行为的唯一方法是,不知怎的,通过DOM树转化为一个字符串,反之亦然事件被删除。有趣的是,使用$ .empty(),如文档中提到的解决了这个问题。
The important part is that $.html expects an html string, not elements and also unbinds any event handlers present on child nodes. The only way I can explain this behavior is that somehow through transformation of the dom tree to a string and vice versa the events get removed. Interestingly enough, using $.empty() as mentioned in the documentation solves the problem.
// any $.html reference needs to have an $.empty too
this.$el.empty().html(this.subView.render().$el);
// and then later for your mainView
$("#area1").empty().html(v.render().$el);
这篇关于Backbone.View:delegateEvents不会再次将事件绑定到子视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!