请参阅工作 jsFiddle:http://jsfiddle.net/ruslans/vFK82/
我有 3 个字段:净价(不含税)、税额和总价(价格不含增值税 + 税额)。
NetPrice 和 Total 是可写的,即您可以更改其中任何一个,而其他 2 个值必须自动计算。
我的方法是使用 3 个可观察对象和 2 个计算淘汰对象,但我想也许更了解淘汰赛的人可以建议一种更有效的方法来实现这一目标。
html:
Net Price:
<input type="textbox" data-bind="value: NetPriceCalc" />
<br />Tax Amount:
<label data-bind="html: TaxAmt"></label>
<br />Total:
<input type="textbox" data-bind="value: TotalCalc" />
script:
var viewModel = {
NetPrice: ko.observable(100),
TaxAmt: ko.observable(20),
Total: ko.observable(120),
TaxRate: 0.2
};
viewModel.updateTaxAmt = function (useNetPrice) {
if (useNetPrice) {
return this.TaxAmt(this.NetPrice() * this.TaxRate);
} else {
var total = Number(this.Total());
var taxAmt = total - total / (1 + this.TaxRate);
return this.TaxAmt(taxAmt);
}
};
viewModel.updateNetPrice = function () {
this.NetPrice(Number(this.Total()) - Number(this.TaxAmt()));
};
viewModel.updateTotal = function () {
this.Total(Number(this.NetPrice()) + Number(this.TaxAmt()));
};
viewModel.NetPriceCalc = ko.computed({
read: function () {
console.log("NetPriceCalc read");
return viewModel.NetPrice();
},
write: function (value) {
console.log("NetPriceCalc write");
viewModel.NetPrice(value);
viewModel.updateTaxAmt(true);
return viewModel.updateTotal();
}
});
viewModel.TotalCalc = ko.computed({
read: function () {
console.log("TotalCalc read");
return viewModel.Total();
},
write: function (value) {
console.log("TotalCalc write");
viewModel.Total(value);
viewModel.updateTaxAmt(false);
return viewModel.updateNetPrice();
}
});
ko.applyBindings(viewModel);
对OP的一些评论:
- 你不需要
return
中的条款write
的方法ko.computed
.
- 您的方法使用
Number()
在多个地方运行,您可能希望更改它以获得特定的精度(或用于验证用户输入的某个集中位置)。所以你可以使用ko.扩展器来改善这一点。我特别推荐 ko 团队已经制作的扩展器,名为ko.extenders.numeric.
- 你的方法还使用
console.log()
在几个地方,你可能想使用 ko 团队制作的另一个 ko.extenderko.extenders.logChange.
- 代替
ko.computed
在这种情况下我认为最好使用subscribe因为它需要更少的代码(并且可能更快)。
我的方法是这样的:
function viewModel() {
this.TaxRate = 0.2;
this.NetPrice = ko.observable().extend({ numeric: 2, logChange: "NetPrice" });
this.TaxAmt = ko.observable().extend({ numeric: 2, logChange: "TaxAmt" });
this.Total = ko.observable().extend({ numeric: 2, logChange: "Total" });
this.NetPrice.subscribe(function (newNetPrice) {
this.TaxAmt(newNetPrice * this.TaxRate);
this.Total(newNetPrice + this.TaxAmt());
}, this);
this.Total.subscribe(function (newTotal) {
this.TaxAmt(newTotal - newTotal / (1 + this.TaxRate));
this.NetPrice(newTotal - this.TaxAmt());
}, this);
this.NetPrice(100);
}
// then I have the extenders code copied exactly as seen in: http://knockoutjs.com/documentation/extenders.html)
ko.extenders.numeric = ...
ko.extenders.logChange = ...
// and finally init everything as usual
ko.applyBindings(new viewModel());
您可以在这里看到工作小提琴:http://jsfiddle.net/protron/JFPgu/2/
请注意,此解决方案中的数字永远不会比数字扩展器上指定的小数位数更多(即使用户输入的值也会自动固定为所需的精度)。
将我的答案与 gaurav 当前接受的答案进行比较(这也非常好且简单):我认为我的方法的主要优点是它可以让您使用这些很棒的扩展器。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)