KnockoutJS和无限循环

时间:2013-08-08 13:53:40

标签: javascript knockout.js

我正在使用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 form准备了一个现场演示。

2 个答案:

答案 0 :(得分:2)

我建议制作一些“私有”可观察量,由可编写的计算可观察量暴露。

使用三个可观察量取决于彼此,通过在一个变化时确定哪个变量保持“固定”,可以防止无限循环的额外风险。

this fiddle中,我按照以下方式完成了这项工作:

  • 如果重量发生变化,时刻会更新,手臂会保持不变。
  • 如果时刻发生变化,手臂会更新,重量会保持不变。
  • 如果手臂发生变化,时刻会更新,重量会保持不变。

“私人”观察者看起来像这样:

_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中的任何一个。只有其中一个可观察者会改变,防止出现循环问题。

答案 1 :(得分:1)

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

我创建了一个fiddle,其中我创建了3个常规observable和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()));
};

我希望它有所帮助。