KnockoutJS和无限循环

KnockoutJS and Infinite Loop

本文关键字:无限循环 KnockoutJS      更新时间:2023-09-26

我正在使用KnockoutJS创建一个简单的飞行重量和平衡应用程序。这涉及到计算臂CCD_ 1和力矩CCD_。正如你们所看到的,手臂取决于力矩,反之亦然。我遇到的问题是,当用户更新瞬间或手臂时,我会得到一个无限循环,我需要打破它。

这是我的代码:

function weightAndBalance(_arm)
{
    var self = this;
    this.weight = ko.observable(0);
    this.arm = ko.computed(function()
    {
        if(parseFloat(self.weight()) == 0)
        {
            return _arm;
        }
        console.log("Arm: " + parseFloat(self.moment()) / parseFloat(self.weight()));
        return parseFloat(self.moment()) / parseFloat(self.weight());
    });
    this.moment = ko.computed(function()
    {
        console.log("Moment: " + parseFloat(self.weight()) * parseFloat(self.arm()));
        return parseFloat(self.weight()) * parseFloat(self.arm());
    });
}
ko.applyBindings(new weightAndBalance(80.1));

我的标记:

<table>
    <tr>
        <th>Item</th>
        <th>Weight</th>
        <th>Arm</th>
        <th>Moment</th>
    </tr>
    <tr>
        <td>Front Passengers</td>
        <td><input type="text" data-bind="value: weight" /></td>
        <td><input type="text" data-bind="value: arm" /></td>
        <td><input type="text" data-bind="value: moment" /></td>
    </tr>
</table>

用户应该输入一个权重,并且应该填充力矩字段。如果手动输入力矩字段,则应自动重新计算手臂。

我准备了一个Fiddle形式的现场演示。

我建议制作一些"私有"可观察性,由同样可写的计算可观察器公开。

由于三个可观察性相互依赖,可以通过决定当一个变量发生变化时哪个变量保持"固定"来防止无限循环的额外风险。

在这把小提琴里,我做到了如下:

  • 如果重量发生变化,则力矩将更新,手臂保持固定
  • 如果力矩发生变化,则手臂将更新,重量保持固定
  • 如果手臂发生变化,则力矩将更新,重量保持固定

"私人"可观测物看起来是这样的:

_weight = ko.observable(parseFloat(initialWeight) || 0);
_arm = ko.observable(parseFloat(initialArm) || 0);
_moment = ko.observable(_weight() * _arm());

然后计算出的三个可观测值如下:

self.weight = ko.computed({
    write: function (val) {
        _weight(parseFloat(val));
        _moment(_arm() * _weight());
    },
    read: _weight
});
self.arm = ko.computed({
    write: function (val) {
        _arm(parseFloat(val));
        _moment(_arm() * _weight());
    },
    read: _arm
});
self.moment = ko.computed({
    write: function(val) {
        _moment(parseFloat(val));
        _arm(_moment() / _weight());
    },
    read: _moment
});

现在,您可以安全地更新三个可观测值中的任何一个。只有一个其他可观察性会发生变化,从而防止循环性问题。

您只在计算机上定义了read方法。如果你想获得键入的信息,你需要添加写入方法。

我创建了一个fiddle,其中创建了3个规则的可观测值和2个处理数据的方法。我认为这样做更简单,而且它是无限循环的。

this.weight = ko.observable(0);
this.arm = ko.observable(0);
this.moment = ko.observable(0);
this.computeArm = function () {
    if (parseFloat(self.weight()) == 0) {
        return _arm;
    }
    console.log("Arm: " + parseFloat(self.moment()) / parseFloat(self.weight()));
    self.arm( parseFloat(self.moment()) / parseFloat(self.weight()));
}

this.computeMoment = function () {
    console.log("Moment: " + parseFloat(self.weight()) * parseFloat(self.arm()));
    self.moment( parseFloat(self.weight()) * parseFloat(self.arm()));
};

我希望它能有所帮助。