Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.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 主干模型更改事件中具有更新属性的无限循环_Javascript_Backbone.js_Infinite Loop_Backbone Events - Fatal编程技术网

Javascript 主干模型更改事件中具有更新属性的无限循环

Javascript 主干模型更改事件中具有更新属性的无限循环,javascript,backbone.js,infinite-loop,backbone-events,Javascript,Backbone.js,Infinite Loop,Backbone Events,我使用主干和ReactJS将一些HTMLdivs(让我们称它们为盒子)堆叠在另一个div(让我们称这个容器)中。用户可以放大这个容器,也可以放大框(与CSS缩放属性无关)。当容器上触发缩放事件时,我计算放大框的总高度,并用堆栈的新高度更新容器。实际的代码很麻烦,下面的代码模拟了导致无限循环的确切场景 在下面的代码中,用户更改ClickButton模型上的缩放值。基于zoom值,我计算新的j并更新它。当j改变时,我也更新了k。现在我处在一个无限循环中,不断增加k的值。通过点击“点击”按钮对代码进行

我使用主干和ReactJS将一些HTML
div
s(让我们称它们为盒子)堆叠在另一个
div
(让我们称这个容器)中。用户可以放大这个容器,也可以放大框(与CSS缩放属性无关)。当容器上触发缩放事件时,我计算放大框的总高度,并用堆栈的新高度更新容器。实际的代码很麻烦,下面的代码模拟了导致无限循环的确切场景

在下面的代码中,用户更改ClickButton模型上的缩放值。基于
zoom
值,我计算新的
j
并更新它。当
j
改变时,我也更新了
k
。现在我处在一个无限循环中,不断增加
k
的值。通过点击“点击”按钮对代码进行测试。变量
k
冲到100(故意在100处中断,否则浏览器将冻结)

我的理解是: 看起来,当我在更改处理程序上更新k或主干模型中的任何内容时,它会创建另一个更改事件。上一个事件结束后,此新事件开始执行。但是,对于函数调用this.hasChanged(“j”),这个新事件仍然返回true,它发生在上一个事件之前,并在上一个事件中处理

当前解决方案: 我使用
{silent:true}
选项作为主干
set
方法的输入,并成功地停止了无限循环

我想用另一种方法来实现这一点,而不抑制更改事件,因为我的HTML页面更新依赖于更改事件。我的ReactJS应用程序连接到模型,并更新模型更改视图

有人知道更好的解决办法吗

var ClickButton=Backbone.Model.extend({
默认值:函数(){
返回{
类名:“显示”,
缩放:0,
j:0,
k:0,
儿童:[],
}
},
初始化(){
getElement(“缩放”).value=this.get(“缩放”);
getElement(“zoomchanged”)。值=0;
关于“变更”,功能(e){
如果(本条已更改(“j”)){
getElement(“j”).value=this.get(“缩放”);
如果(此项获得(“k”)<100){
//刚刚添加了100个,您的浏览器不会被卡住
this.set(“k”),parseInt(this.get(“k”))+1);
getElement(“k”).value=parseInt(this.get(“k”));
}
}
如果(此.hasChanged(“缩放”)){
getElement(“zoomchanged”).value=parseInt(getElement(“zoomchanged”).value)+1;
console.log(this.get(“zoom”);
getElement(“缩放”).value=this.get(“缩放”);
this.set(“j”,this.get(“zoom”);
}
});
}
});
var clickButton=新的clickButton();
var button=getElement(“按钮”);
按钮。addEventListener(“单击”),功能(e){
var currentValueOfZoom=点击按钮。获取(“缩放”);
单击按钮。设置(“缩放”,当前缩放值+1);
}).约束(这个);
//助手
函数getElement(类名){
返回单据.getElementsByClassName(类名)[0];
}
输入{
宽度:35px;
}
div#holder{
显示器:flex;
}
div#holder输入{
右边距:23px;
}

K:
J:
缩放:
缩放更改次数:
点击
主干网的
静默:true
可以防止这种行为。但是,如文档中所述,更好的解决方案是传递一个特定的标志(例如我在下面的代码段中传递并检查的
ignore:true
标志)

从主干文档:

一般来说,在调用发出事件的函数(model.set、collection.add等)时,如果要防止触发事件,可以将{silent:true}作为选项传递。请注意,这很少,甚至从来都不是一个好主意。在选项中传递一个特定的标志以供事件回调查看,并选择忽略,通常效果会更好

虽然针对您的情况提供了一个工作补丁,但我还是想分享一下最佳实践

发生了什么事? 仅返回通过
集合所做的最新更改,不跟踪任何其他后续更改,除非这些更改是在相关触发事件中进行的。一旦
集合
完成,对
集合
的任何后续调用都将覆盖该集合

由于在一般的
change
事件中更改
zoom
j
k
,因此任何后续的
set
都会触发一个新的
change
事件,其中
hasChanged
始终返回true,因为
changed
属性如下所示:

{
    zoom: 1,
    j: 1,
    k: 100,
}
如何解决这个无限循环? 可以做很多事情来简化和改进您的模型。首先,不要在主干模型中使用DOM。这是视图的工作,所以在您的情况下做出反应

记住这一点,使用处理程序(
change:[attribute]



尽管如此,我不确定主干模型是否是处理按钮点击的好选择。但话说回来,您还没有共享React代码…

谢谢。这就解决了问题+1因为我从来不知道我可以将自定义数据作为选项传递。我一直认为选项就像主干内部指令一样,{silent:true}将在更改事件时抑制。
{
    zoom: 1,
    j: 1,
    k: 100,
}
var ClickButton = Backbone.Model.extend({
    defaults: {
        zoom: 0,
        j: 0,
        k: 0,
    },
    initialize() {
        this.listenTo(this, {
            'change:zoom': this.onZoomChange,
            'change:j': this.onJChange
        });
    },
    onZoomChange(model, value, options) {
        this.set("j", this.get("zoom"));
    },
    onJChange(model, value, options) {
        this.set("k", parseInt(this.get("k")) + 1);
    }
});