如何打破淘汰模型订阅者的循环依赖?
How to break circular dependency in knockout model subscriber?
我正在使用 Knockout 构建模型。我有一个 parent 模型和一对 children。每个 children 有 obsevrable
(computed
在工作代码中,但它不会改变情况) isLoading
其中 return true
当任何内部操作时模型已处理。
Parent 模型还计算了 isLoading
有订阅者。在这个订阅者中,我只想执行一次代码(我有特殊标志,没关系)。我的问题是这段代码以某种方式改变了一个 child 的 isLoading
状态。在那里我发现它不会引发 parent computed changed.
如何解决这种循环依赖?
示例 fiddle:http://jsfiddle.net/202x4755/
UPD:重点是使用setTimeout
您应该将 onStateChanged
函数订阅到每个子模型的 isLoading
observable 而不是父模型的 isLoading
observable。
self.submodels().forEach(function (submodel) {
submodel.isLoading.subscribe(onStateChanged);
});
您可以使循环更新异步。因为你总是有通知,所以你应该确保在启动之前更新是必要的,否则你将进入永久更新循环。
对于这个例子,您的订阅实际上应该(仅)在子模型()[1] 上,但我们假设您还有其他事情需要它在父模型上。
function onStateChanged(value) {
console.log('onStateChanged ' + value);
// If second model finished loading automatically mark last model as loaded also
if (!self.submodels()[1].isLoading() && self.submodels()[2].isLoading()) {
setTimeout(function () {
console.debug("Forcing submodel isloading to false");
self.submodels()[2].isLoading(false);
}, 0);
}
}
我正在使用 Knockout 构建模型。我有一个 parent 模型和一对 children。每个 children 有 obsevrable
(computed
在工作代码中,但它不会改变情况) isLoading
其中 return true
当任何内部操作时模型已处理。
Parent 模型还计算了 isLoading
有订阅者。在这个订阅者中,我只想执行一次代码(我有特殊标志,没关系)。我的问题是这段代码以某种方式改变了一个 child 的 isLoading
状态。在那里我发现它不会引发 parent computed changed.
如何解决这种循环依赖?
示例 fiddle:http://jsfiddle.net/202x4755/
UPD:重点是使用setTimeout
您应该将 onStateChanged
函数订阅到每个子模型的 isLoading
observable 而不是父模型的 isLoading
observable。
self.submodels().forEach(function (submodel) {
submodel.isLoading.subscribe(onStateChanged);
});
您可以使循环更新异步。因为你总是有通知,所以你应该确保在启动之前更新是必要的,否则你将进入永久更新循环。
对于这个例子,您的订阅实际上应该(仅)在子模型()[1] 上,但我们假设您还有其他事情需要它在父模型上。
function onStateChanged(value) {
console.log('onStateChanged ' + value);
// If second model finished loading automatically mark last model as loaded also
if (!self.submodels()[1].isLoading() && self.submodels()[2].isLoading()) {
setTimeout(function () {
console.debug("Forcing submodel isloading to false");
self.submodels()[2].isLoading(false);
}, 0);
}
}