如何处理自增自减ko.observables浮点数
How to deal with incrementing and decrementing ko.observables floating point
这里准备了一个小jsfiddle:jsfiddle.net/v8s176p2
基本上我想以 0.1 的步长递增和递减 observable 但由于数字表示和精度问题,数字有时会显示 as:1.3200000000000003...等,你我希望它们只显示并具有带 1 个小数点的值
我如何在 knockout.js 中编写完全相同的功能,但不使用浮点数。所以我的起始值为 10,在 HTML 中它显示为 1,如果我将它减去 (10-1 = 9) 在 html 中它显示为 0.9?对于我的应用程序来说,这可能是更好的方法,因为我是从嵌入式设备上的服务器获取这些数据的,所以最好将数字接收为 200,然后将其除以 10,但是如何在 ko.js 在我的示例中 fiddle?
您可以创建一个自定义绑定,像这样
ko.bindingHandlers.numericText = {
update: function (element, valueAccessor, allBindingsAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
var formattedValue = value.toFixed(2);
ko.bindingHandlers.text.update(element, function () { return formattedValue; });
}
};
在那里您可以根据需要格式化值,然后像这样使用它:
<p data-bind="numericText: num1"></p>
处理整数并在文本绑定中进行除法以显示浮点数。这会将支持数据保留为整数,因此不会累积错误。
data-bind="text: num1() / 10"
另一种方法是将计算的可观察对象添加到可观察对象 属性 中,例如
var vm = function(){
var self = this;
self.num1 = ko.observable();
self.num1.formatted = ko.computed(function(){ return Math.round((self.num1()*10),0)/10; });
}
这种格式包含在视图模型中,将 vm
对象转换为 JSON 将忽略输出中的格式化计算函数。
要使用它,
<p data-bind="text: num1.formatted"></p>
另一种选择是使用可写的计算可观察对象。
我在以下代码段中包含了这两种技术。
var increment = function(observable) {
observable(observable() + 0.1);
};
var decrement = function(observable) {
observable(observable() - 0.1);
};
var MyViewModel = function() {
var self = this;
self.num1 = ko.observable(0);
self.num1.formatted = ko.computed(function() {
return Math.round((self.num1() * 10), 0) / 10;
});
var num2BackingProperty = ko.observable(0);
self.num2 = ko.computed({
read: function() {
return num2BackingProperty();
},
write: function(value) {
num2BackingProperty(Math.round((value * 10), 0) / 10);
},
owner: self
})
this.incrementNum = function(observable) {
// passing the observable by reference to the helper function
increment(observable);
};
this.decrementNum = function(observable) {
decrement(observable);
};
}
ko.applyBindings(new MyViewModel());
h3 {
font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script>
<button data-bind="click: incrementNum.bind($root, num1)">Increment Num1</button>
<button data-bind="click: decrementNum.bind($root, num1)">Decrement Num1</button>
<h3>
Formatted
</h3>
<p data-bind="text: num1.formatted"></p>
<h3>
Unformatted
</h3>
<p data-bind="text: num1"></p>
<br/>
<br/>
<button data-bind="click: incrementNum.bind($root, num2)">Increment Num2</button>
<button data-bind="click: decrementNum.bind($root, num2)">Decrement Num2</button>
<h3>
Writable Computed
</h3>
<p data-bind="text: num2"></p>
<br/>
<h3>
View Model Json
</h3>
<pre data-bind="text: ko.toJSON($root)"></pre>
这里准备了一个小jsfiddle:jsfiddle.net/v8s176p2
基本上我想以 0.1 的步长递增和递减 observable 但由于数字表示和精度问题,数字有时会显示 as:1.3200000000000003...等,你我希望它们只显示并具有带 1 个小数点的值
我如何在 knockout.js 中编写完全相同的功能,但不使用浮点数。所以我的起始值为 10,在 HTML 中它显示为 1,如果我将它减去 (10-1 = 9) 在 html 中它显示为 0.9?对于我的应用程序来说,这可能是更好的方法,因为我是从嵌入式设备上的服务器获取这些数据的,所以最好将数字接收为 200,然后将其除以 10,但是如何在 ko.js 在我的示例中 fiddle?
您可以创建一个自定义绑定,像这样
ko.bindingHandlers.numericText = {
update: function (element, valueAccessor, allBindingsAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
var formattedValue = value.toFixed(2);
ko.bindingHandlers.text.update(element, function () { return formattedValue; });
}
};
在那里您可以根据需要格式化值,然后像这样使用它:
<p data-bind="numericText: num1"></p>
处理整数并在文本绑定中进行除法以显示浮点数。这会将支持数据保留为整数,因此不会累积错误。
data-bind="text: num1() / 10"
另一种方法是将计算的可观察对象添加到可观察对象 属性 中,例如
var vm = function(){
var self = this;
self.num1 = ko.observable();
self.num1.formatted = ko.computed(function(){ return Math.round((self.num1()*10),0)/10; });
}
这种格式包含在视图模型中,将 vm
对象转换为 JSON 将忽略输出中的格式化计算函数。
要使用它,
<p data-bind="text: num1.formatted"></p>
另一种选择是使用可写的计算可观察对象。 我在以下代码段中包含了这两种技术。
var increment = function(observable) {
observable(observable() + 0.1);
};
var decrement = function(observable) {
observable(observable() - 0.1);
};
var MyViewModel = function() {
var self = this;
self.num1 = ko.observable(0);
self.num1.formatted = ko.computed(function() {
return Math.round((self.num1() * 10), 0) / 10;
});
var num2BackingProperty = ko.observable(0);
self.num2 = ko.computed({
read: function() {
return num2BackingProperty();
},
write: function(value) {
num2BackingProperty(Math.round((value * 10), 0) / 10);
},
owner: self
})
this.incrementNum = function(observable) {
// passing the observable by reference to the helper function
increment(observable);
};
this.decrementNum = function(observable) {
decrement(observable);
};
}
ko.applyBindings(new MyViewModel());
h3 {
font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script>
<button data-bind="click: incrementNum.bind($root, num1)">Increment Num1</button>
<button data-bind="click: decrementNum.bind($root, num1)">Decrement Num1</button>
<h3>
Formatted
</h3>
<p data-bind="text: num1.formatted"></p>
<h3>
Unformatted
</h3>
<p data-bind="text: num1"></p>
<br/>
<br/>
<button data-bind="click: incrementNum.bind($root, num2)">Increment Num2</button>
<button data-bind="click: decrementNum.bind($root, num2)">Decrement Num2</button>
<h3>
Writable Computed
</h3>
<p data-bind="text: num2"></p>
<br/>
<h3>
View Model Json
</h3>
<pre data-bind="text: ko.toJSON($root)"></pre>