我正在使用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准备了一个现场演示。
答案 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()));
};
我希望它有所帮助。