3

我正在使用 KnockoutJS 创建一个用于飞行的简单重量和平衡应用程序。这涉及计算手臂(moment / weight)和力矩(weight * arm)。如您所见,手臂取决于力矩,反之亦然。我遇到的问题是当用户更新时刻或手臂时,我得到一个无限循环,我需要打破它。

这是我的代码:

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 形式的现场演示。

4

2 回答 2

2

我建议制作一些“私有”的 observables,通过计算的 observables 公开,这些 observables 也是可写的。

由于三个observables 相互依赖,因此可以通过确定在一个变量发生变化时哪个变量保持“固定”来防止无限循环的额外风险。

这个小提琴中,我做了如下:

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

“私有”可观察对象如下所示:

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

那么三个计算出来的 observable 看起来像这样:

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
});

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

于 2013-08-08T14:36:13.363 回答
1

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

我创建了一个小提琴,在其中创建了 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()));
};

我希望它有所帮助。

于 2013-08-08T14:23:37.757 回答