Knockout.js中的相互递归字段
我想在knockout.js中解决以下问题:我有三个输入<代码>价格,Knockout.js中的相互递归字段,knockout.js,Knockout.js,我想在knockout.js中解决以下问题:我有三个输入价格,数量和总计,我要在其中设置 total = price * quantity price = total / quantity 当我更新价格或数量时,我还想设置 total = price * quantity price = total / quantity 如果我更新总数 我最初是用一个计算的可观测值来做这件事的,但是这几乎不起作用,但是我有一个取整的问题。如果我这样做了 quantity(3) total
数量
和总计
,我要在其中设置
total = price * quantity
price = total / quantity
当我更新价格
或数量
时,我还想设置
total = price * quantity
price = total / quantity
如果我更新总数
我最初是用一个计算的可观测值来做这件事的,但是这几乎不起作用,但是我有一个取整的问题。如果我这样做了
quantity(3)
total(100)
我希望price
设置为33.33,只有两个小数,而total
仍应设置为100,因此标识total=price*quantity
不太合适
在我采用的计算可观察方法中,在这种情况下,total
将设置为99.99。这就是为什么这种情况不同于文档中的fullname/firstname/lastname示例
本质上,
价格
/总计
字段是相互递归的。除了手动订阅之外,我找不到解决这个问题的好方法,但这感觉很不自然,这意味着我必须手动处理大量订阅等。我也做了类似的事情,制作了“真实价值”ko。可观察(即数量、价格和总数),跟踪表单字段上的焦点事件,并使用ko.computed()重新计算(但如果选择了当前字段,则不进行计算)并格式化表单的值
这一句话的描述听起来很复杂,但在代码方面并没有那么复杂
JavaScript:
var Model = function () {
var self = this;
self.quantity = ko.observable(0);
self.price = ko.observable(0);
self.price.selected = ko.observable(false);
self.total = ko.observable(0);
self.total.selected = ko.observable(false);
self.formattedPrice = ko.computed({
read: function () {
if (!self.price.selected()) {
var total = self.total() || 0;
var quantity = self.quantity() || 0;
var value = total / quantity;
self.price(isNaN(value) ? 0 : value);
}
return '$' + self.price().toFixed(2);
},
write: function (value) {
value = parseFloat(value.replace(/[^\.\d]/g, ""));
self.price(isNaN(value) ? 0 : value);
}
});
self.formattedTotal = ko.computed({
read: function () {
if (!self.total.selected()) {
var quantity = self.quantity() || 0;
var price = self.price() || 0;
var value = quantity * price;
self.total(isNaN(value) ? 0 : value);
}
return '$' + self.total().toFixed(2);
},
write: function (value) {
value = parseFloat(value.replace(/[^\.\d]/g, ""));
self.total(isNaN(value) ? 0 : value);
}
});
};
ko.applyBindings(new Model());
在HTML中,您可以这样绑定price和total:
如果您想查看工作示例,请在处编写代码。我做了类似的事情,制作了“真实值”ko.observables(即数量、价格和总数),跟踪表单字段上的焦点事件,并使用ko.computed()重新计算(但如果选择了当前字段,则不进行计算)和格式化表单的值 这一句话的描述听起来很复杂,但在代码方面并没有那么复杂 JavaScript:
var Model = function () {
var self = this;
self.quantity = ko.observable(0);
self.price = ko.observable(0);
self.price.selected = ko.observable(false);
self.total = ko.observable(0);
self.total.selected = ko.observable(false);
self.formattedPrice = ko.computed({
read: function () {
if (!self.price.selected()) {
var total = self.total() || 0;
var quantity = self.quantity() || 0;
var value = total / quantity;
self.price(isNaN(value) ? 0 : value);
}
return '$' + self.price().toFixed(2);
},
write: function (value) {
value = parseFloat(value.replace(/[^\.\d]/g, ""));
self.price(isNaN(value) ? 0 : value);
}
});
self.formattedTotal = ko.computed({
read: function () {
if (!self.total.selected()) {
var quantity = self.quantity() || 0;
var price = self.price() || 0;
var value = quantity * price;
self.total(isNaN(value) ? 0 : value);
}
return '$' + self.total().toFixed(2);
},
write: function (value) {
value = parseFloat(value.replace(/[^\.\d]/g, ""));
self.total(isNaN(value) ? 0 : value);
}
});
};
ko.applyBindings(new Model());
在HTML中,您可以这样绑定price和total:
如果您想查看工作示例,请在处编写代码。谢谢您的回答。仅供参考,这是我目前拥有的解决方案,除非它给我带来问题,否则我可能会坚持下去
var self = this;
this.price = ko.observable().extend({numeric: 2});
this.quantity = ko.observable(1).extend({ numeric: 2 });
this.total = ko.observable(1).extend({ numeric: 2 });
var unsub_total = this.total.subscribe(function (total) {
if (self.quantity() != 0)
self.price(total / self.quantity())
});
// setting quantity will update both price and total
var unsub_qty = this.quantity.subscribe(function (qty) {
self.total(self.price() * qty);
});
var unsub_price = this.price.subscribe(function (price) {
self.total(price * self.quantity());
});
this.unsub = function() { unsub_total(); unsub_price(); unsub_qty(); };
谢谢你的回答。仅供参考,这是我目前拥有的解决方案,除非它给我带来问题,否则我可能会坚持下去
var self = this;
this.price = ko.observable().extend({numeric: 2});
this.quantity = ko.observable(1).extend({ numeric: 2 });
this.total = ko.observable(1).extend({ numeric: 2 });
var unsub_total = this.total.subscribe(function (total) {
if (self.quantity() != 0)
self.price(total / self.quantity())
});
// setting quantity will update both price and total
var unsub_qty = this.quantity.subscribe(function (qty) {
self.total(self.price() * qty);
});
var unsub_price = this.price.subscribe(function (price) {
self.total(price * self.quantity());
});
this.unsub = function() { unsub_total(); unsub_price(); unsub_qty(); };