在为名为candy-calc的在线计算器框架开发代码时,我有两个ko.observables
名为calcVar1.selUnit
和calcVar2.selUnit
,我希望将它们连接在一起。我的意思是,如果一个人改变,另一个人会改变,反之亦然。我试图解决这个问题的方法是创建两个显示变量calcVar1.dispSelUnit和calcVar2.dispSelUnit
,它们是ko.computed()
。它们在视图中绑定,并且它们具有不同的读/写功能,如下所示。
// Modified write function
calcVar1.dispSelUnit = ko.computed({
read : function(){
console.log('Reading source var sel unit.');
// Return as usual
return calcVar1.selUnit();
},
write : function(value){
// Write to both of them
console.log('Writing ' + value + 'to both sel unit.');
calcVar1.selUnit(value);
calcVar2.selUnit(value);
},
owner : this
});
// Modified write function
calcVar2.dispSelUnit = ko.computed({
read : function(){
console.log('Reading destination var sel unit.');
// Make it equal to the source variables selected unit
return calcVar2.selUnit();
},
write : function(value){
// Write to both of them
console.log('Writing ' + value + 'to both sel unit.');
calcVar1.selUnit(value);
calcVar2.selUnit(value);
},
owner : this
});
}
基本上,dispSelUnits
充当下面真实selUnit
值的中介,并且在写入更新时selUnit
(ko.observables
),而在读取行为时像平常一样。
我看不出这个逻辑有什么问题。但是,在运行此操作时,如果我尝试更新compVar1.dispSelUnit
,它会进入无限循环,其中compVar1.dispSelUnit
被写入然后读取,然后compVar2.dispSelUnit
被写入并读取,然后再返回。
答案 0 :(得分:3)
我们也在Github(https://github.com/mbest/knockout-deferred-updates/issues/17)上讨论过这个问题。在查看他的代码之后,我做了以下观察和建议。
你得到了递归问题,因为这两个变量有value
绑定到选择具有不同单位列表的框。虽然它们显示相同的单位,但它们实际上是不同的对象。 value
绑定始终尝试将observable设置为列表中当前选定的项。但由于列表不同,这实际上是不可能的,并且可观察量在两个值之间无休止地切换。
要解决此问题,您需要两个选择框来引用相同的对象。在standard-resistance-finder.js
中,执行以下操作:
var resistenceUnits = [
new cc.unit('m\u2126', 0.001),
new cc.unit('\u2126', 1.0),
new cc.unit('k\u2126', 1000.0)
];
this.desiredRes = new cc.input(
this,
function() { return true; },
resistenceUnits,
0);
...
this.actualRes = new cc.output(
this,
...
resistenceUnits,
0, 2);
关于保持两个可观察对象同步的问题,这个问题可能会提供一些答案:Simple, clean way to sync observables from different view models