Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 主干视图:delegateEvents未将事件重新绑定到子视图_Javascript_Jquery_Backbone.js - Fatal编程技术网

Javascript 主干视图:delegateEvents未将事件重新绑定到子视图

Javascript 主干视图:delegateEvents未将事件重新绑定到子视图,javascript,jquery,backbone.js,Javascript,Jquery,Backbone.js,我已经将这个问题分解为尽可能小的示例(即,它只是为了演示问题,而不一定代表真实世界的场景) 假设我有一个父视图(此处为“MainView”),其中包含一个子视图(此处为“SubView”)。如果在任何时候,我需要重新呈现父视图(从而重新呈现子视图),我将丢失子视图中的事件绑定,尽管调用了delegateEvents 可以在以下位置找到JSFIDLE: 以下是完整的代码: var MainView = Backbone.View.extend({ tagName : "div",

我已经将这个问题分解为尽可能小的示例(即,它只是为了演示问题,而不一定代表真实世界的场景)

假设我有一个父视图(此处为“MainView”),其中包含一个子视图(此处为“SubView”)。如果在任何时候,我需要重新呈现父视图(从而重新呈现子视图),我将丢失子视图中的事件绑定,尽管调用了
delegateEvents

可以在以下位置找到JSFIDLE:

以下是完整的代码:

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
var MainView=Backbone.View.extend({
标记名:“div”,
初始化:函数(){
this.subView=新建子视图();
},
render:function(){
this.$el.html(this.subView.render().$el);//.html()中断绑定
this.subView.delegateEvents();//这将重新建立它们
归还这个;
}
});
var SubView=Backbone.View.extend({
标记名:“div”,
活动:{
单击按钮1:“按按钮按”
},
onButtonPress:function(){
警报(“按下按钮”);
},
render:function(){
var html=“Button1”;
这个.$el.html(html);
归还这个;
}
});
var v=新的主视图();
$(“#区域1”).html(v.render().$el);//他工作得很好
//做一些工作。。。然后重新渲染。。。
$(“#区域1”).html(v.render().$el);//中断事件绑定

我不明白为什么会这样。任何输入都将不胜感激。

要保留绑定,您可以做三件事

使用$.append而不是$.html 使用
$.append
将保持绑定的完整性,并注意不要丢失任何兄弟内容

只需重新渲染而无需重新附加 在代码中,您可以重新呈现视图并重新附加其内容。这是没有必要的。只需调用
v.render()
即可获得相同的视觉效果,但保持绑定完好无损

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() 根据

如果保留对这些DOM元素的引用并且需要它们保持不变,请使用.empty().html(字符串)而不是.html(字符串),以便在将新字符串分配给元素之前从文档中删除这些元素

重要的一点是,$.html需要一个html字符串,而不是元素,并且还取消绑定子节点上的任何事件处理程序。我能解释这种行为的唯一方法是,通过将dom树转换为字符串,或者反过来,事件被删除。有趣的是,使用文档中提到的$.empty()可以解决这个问题

// 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);

谢谢你的建议。我避免使用
append
,因为它强制javascript指定元素的顺序。至于第二个建议,虽然这在本例中有效,但如果
MainView
本身是另一个父视图的子视图,则不起作用。JSFIDLE:我更新了我的答案,参考了jQuery文档和
$.html
的工作解决方案。那很有趣。我注意到jQuery文档提到,只有IE中的文本内容损坏才需要这样的步骤,但这个问题似乎发生在每个浏览器上(不管怎样,我到目前为止测试过的所有浏览器)。我想知道这个问题是:(a)未被记录的预期行为,还是(b)使用另一个问题的解决方案发现了解决方法的意外行为。感谢您的解决方案并解释了
.html()
的jquery陷阱,很高兴了解它!