gpt4 book ai didi

javascript - 计算 knockout 的循环依赖

转载 作者:数据小太阳 更新时间:2023-10-29 04:11:49 25 4
gpt4 key购买 nike

查看工作中的 jsFiddle:http://jsfiddle.net/ruslans/vFK82/

我有 3 个字段:净价(不含税)、税额和总价(不含增值税的价格 + 税额)。NetPrice 和 Total 是可写的,即您可以更改其中一个,而其他 2 个值必须自动计算。

我的做法是使用 3 个可观察对象和 2 个计算出的 knockout 对象,但我想也许更了解 knockout 的人可以建议一种更有效的方法来实现这一目标。

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" />

脚本:

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 的一些评论:

  • 您不需要ko.computedwrite 方法中的return 子句。
  • 您的方法在多个地方使用了 Number() 函数,您可能希望更改它以获得特定的精度(或某个用于验证用户输入的集中位置)。所以你可以使用 ko.extenders改善这一点。我会特别推荐名为 ko.extenders.numeric 的 ko 团队已经制作的扩展器。 .
  • 您的方法还在多个地方使用了 console.log(),您可能想使用 ko 团队制作的另一个 ko.extender ko.extenders.logChange .
  • 在这种情况下,我认为最好使用 subscribe 而不是 ko.computed因为它需要更少的代码(而且速度可能微不足道)。

我的方法是这样的:

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

你可以在这里看到工作 fiddle : http://jsfiddle.net/protron/JFPgu/2/

请注意此解决方案中的数字如何永远不会超过数字扩展器上指定的小数位数(即使用户输入的值也会自动固定为所需的精度)。

并将我的答案与 gaurav 目前接受的答案进行比较(这也非常好和简单):我认为我的方法的主要优点是它可以让您使用这些很棒的扩展器。

关于javascript - 计算 knockout 的循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15920306/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com