我正在使用Backbone和ReactJS来保留很少的HTML div
(让我们称之为盒子)堆叠在另一个div
内(让我们调用这个容器)。用户可以放大这个也放大框的容器(与CSS缩放属性无关)。当在容器上触发缩放事件时,我计算放大框的总高度,并使用堆栈的新高度更新容器。实际代码很麻烦,遵循代码模拟确切场景导致无限循环。
在以下代码中,用户更改ClickButton模型的缩放值。根据{{1}}值,我计算新的zoom
并更新它。 j
更改后,我还更新了k
。现在我处于递增j
值的无限循环中。点击"点击"在代码上对此进行测试按钮。变量k
冲到100(故意在100处中断,否则浏览器将冻结)
我的理解:
看起来当我在更改处理程序中更新k或Backbone模型中的任何内容时,它会创建另一个更改事件。一旦前一个事件结束,这个新事件就开始执行。但是,对于函数调用k
,此新事件仍然返回true,该函数在上一个事件之前发生并处理。
目前的解决方案:
我使用this.hasChanged("j")
选项作为Backbone {silent : true}
方法的输入,并成功地阻止了无限循环。
我希望采用另一种方法来做到这一点,而不会抑制更改事件,因为我更新HTML页面依赖于更改事件。我的ReactJS应用程序连接到模型,它更新了模型更改的视图。
任何人都知道更好的解决方案吗?
set

var ClickButton = Backbone.Model.extend({
defaults: function() {
return {
className: "display",
zoom: 0,
j: 0,
k: 0,
children: [],
}
},
initialize() {
getElement("zoom").value = this.get("zoom");
getElement("zoomchanged").value = 0;
this.on("change", function(e) {
if (this.hasChanged("j")) {
getElement("j").value = this.get("zoom");
if (this.get("k") < 100) {
// Just added hundred that your browser wont get stuck
this.set("k", parseInt(this.get("k")) + 1);
getElement("k").value = parseInt(this.get("k"));
}
}
if (this.hasChanged("zoom")) {
getElement("zoomchanged").value = parseInt(getElement("zoomchanged").value) + 1;
console.log(this.get("zoom"));
getElement("zoom").value = this.get("zoom");
this.set("j", this.get("zoom"));
}
});
}
});
var clickButton = new ClickButton();
var button = getElement("button");
button.addEventListener("click", (function(e) {
var currentValueOfZoom = clickButton.get("zoom");
clickButton.set("zoom", currentValueOfZoom + 1);
}).bind(this));
// Helpers
function getElement(className) {
return document.getElementsByClassName(className)[0];
}
&#13;
input {
width: 35px;
}
div#holder {
display: flex;
}
div#holder input {
margin-right: 23px;
}
&#13;
答案 0 :(得分:1)
Backbone的userName = _spPageContextInfo.userDisplayName
option可以防止这种行为。但是,如文档中所述,更好的解决方案是传递一个特定的标志(例如我正在传递的silent:true
标志并在下面的代码片段中进行检查。)
来自骨干文档:
一般来说,当调用发出事件的函数(model.set,collection.add等等)时,如果你想阻止事件被触发,你可以通过{silent:是的}作为一种选择。请注意,这很少,甚至从来都不是一个好主意。通过选项中的特定标志来查看事件回调,并选择忽略,通常会更好。
ignore: true
答案 1 :(得分:0)
虽然lucasjackson提供了针对您情况的工作补丁,但我还是希望分享最佳做法。
.hasChanged
仅返回通过set
所做的最新更改,并且不会跟踪任何其他后续更改,除非它们是在相关的触发事件中进行的。完成set
后,对set
的任何后续调用都将覆盖changed
property。
由于您在通用zoom
事件中更改了j
,k
和change
,因此任何后续set
都会触发新的change
事件hasChanged
总是返回true,因为changed
属性如下所示:
{
zoom: 1,
j: 1,
k: 100,
}
可以做很多事情来简化和改进您的模型。首先,不要在Backbone模型中使用DOM。这是视图的工作,所以React在你的情况下。
考虑到这一点,请使用specific attribute change event处理程序(change:[attribute]
)。
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);
}
});
话虽这么说,我不确定Backbone Model是处理按钮点击的好选择。但话说回来,你还没有分享React代码......