【问题标题】:Connecting Two Knockout Variables Together Without Causing Recursion将两个敲除变量连接在一起而不引起递归
【发布时间】:2013-12-07 00:36:44
【问题描述】:

在为名为@9​​87654321@ 的在线计算器框架开发代码时,我有两个ko.observables,名为calcVar1.selUnitcalcVar2.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 被写入和读取,然后再次返回。

【问题讨论】:

  • 您在那些读/写函数中还做其他事情吗?如果没有,为什么不立即绑定到原始变量?
  • 写入函数被修改,它更新了两个变量而不是一个变量(见上文)。
  • 但是如果两个变量总是同步的,为什么不绑定到其中一个变量呢?为什么你首先有两个变量?他们是否有其他地方更新(单独?
  • 这个“写给selUnitdispSelUnit”是我试图让它们同步的方式。
  • 但是它们是在其他地方单独更新的吗?

标签: javascript recursion binding knockout.js freeze


【解决方案1】:

我们还在 Github (https://github.com/mbest/knockout-deferred-updates/issues/17) 上讨论了这个问题。看了他的代码后,我做了如下观察和建议。

您遇到了递归问题,因为这两个变量具有value 绑定来选择具有不同单位列表的框。尽管它们显示相同的单位,但它们实际上是不同的对象。 value 绑定总是尝试将 observable 设置为列表中当前选定的项目。但是由于列表不同,这真的是不可能的,并且 observables 在两个值之间无休止地切换。

要解决此问题,您需要两个选择框来引用相同的对象。在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);

关于保持两个 observables 同步的问题,这个问题可能会提供一些答案:Simple, clean way to sync observables from different view models

【讨论】:

  • 非常感谢,非常感谢您花时间查看代码。
猜你喜欢
  • 1970-01-01
  • 2015-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-04
  • 1970-01-01
相关资源
最近更新 更多