如果两个依赖路径改变为可观察的,则Knockout在单个动作上计算多次触发
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如果两个依赖路径改变为可观察的,则Knockout在单个动作上计算多次触发相关的知识,希望对你有一定的参考价值。
我有一个可观察的A绑定到UI元素。我还有一个取决于A的计算B。我有一个取决于A和B的计算С。我有一个订阅C
当UI元素中的值发生更改时,计算结果将被计算两次,订阅将被调用两次。
我认为原因是A有两个订阅:A:[B,C] Knockout通知B关于A的变化。 在评估B之后,它通知C关于B的变化 然后它回到开始并调用A的第二个订阅,即C. 这里我们有两个C调用。
有办法防止这种情况吗?
var viewModel = {
firstName: ko.observable("Andrew"),
lastName: ko.observable("King"),
};
viewModel.fullName = ko.computed(function() {
return viewModel.firstName() + " " + viewModel.lastName();
});
viewModel.user = ko.computed(function() {
return {
fullName: viewModel.fullName(),
lastName: viewModel.lastName()
};
});
viewModel.user.subscribe(function() {
// This is called once if I change first name
// It is called twice if I change last name
});
答案
当其中一个依赖项发生更改时,observable会重新计算。由于您在每次运行时都在创建一个新对象,因此淘汰赛无法判断某些内容是否真的发生了变化。
使用延迟计算修复它
为了防止它在两个依赖项发生更改时多次运行,可以将其延迟:
var viewModel = {
firstName: ko.observable("Andrew"),
lastName: ko.observable("King"),
};
viewModel.fullName = ko.computed(function() {
return viewModel.firstName() + " " + viewModel.lastName();
});
viewModel.user = ko.computed(function() {
return {
fullName: viewModel.fullName(),
lastName: viewModel.lastName()
};
}).extend({ deferred: true });
viewModel.user.subscribe(function(user) {
console.log(user);
});
viewModel.firstName("John");
viewModel.lastName("Doe");
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
以上是关于如果两个依赖路径改变为可观察的,则Knockout在单个动作上计算多次触发的主要内容,如果未能解决你的问题,请参考以下文章
当使用knockout.js和Sammy.js时,如何设置内容来自模板的可观察路径