Knockout bindingHandler用于逗号分隔的数字 [英] Knockout bindingHandler for comma separated numbers
问题描述
我正在KnockoutJS中构建一个数量很多的应用程序,我希望能够格式化大数字,以便它们以逗号分隔并且很好看(xxx,xxx)。
I'm building a very number-heavy app in KnockoutJS and I want to have the ability to format large numbers so that they're comma-seperated and nice on the eye (xxx,xxx).
正如您将从下面的小提琴中看到的那样,我确实通过使用简单的RegEx将绑定值包装在格式化函数内部,但问题是这会覆盖值在输入内部并将','插入基础值。
As you'll see from the fiddle below, I do have this working by wrapping the binded value inside of a formatting function with a simple RegEx but the problem with this is that this overwrites the value inside the input and inserts ',' into the underlying value.
大数字在应用程序的下方使用,因此为了防止NaN错误,我必须分配一个data属性为包含没有','的值的输入值,这是存储在sessionStorage中的值。
The large numbers are used further down the app and so to prevent NaN errors I've had to assign a data attribute to the input value containing the value with no ',' and this is the value that gets stored in sessionStorage.
我觉得我的HTML标记不知不觉地膨胀了,并且相信我想要实现的是使用bindingHandler,但我的绑定处理程序并不完全存在。
I feel that I have unncessarily bloated my HTML markup and believe that what I want to achieve is possible with a bindingHandler but my binding handler isn't quite there.
小提琴: http://jsfiddle.net/36sD9/2
formatLargeNumber = function (number) {
if (typeof (number) === 'function') {
return number().toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
}
ko.bindingHandlers.largeNumber = {
init: function(element, valueAccessor) {
var value = ko.unwrap(valueAccessor());
var interceptor = ko.computed({
read: function() {
return formatLargeNumber(value);
},
write: function(newValue) {
value(reverseFormat(newValue));
}
});
if(element.tagName == 'input' )
ko.applyBindingsToNode(element, {
value: interceptor
});
else
ko.applyBindingsToNode(element, {
text: interceptor
});
}
}
任何想法?
推荐答案
您当前的方法存在多个问题:
You have multiple problems with your current approach:
-
element.tagName
返回INPUT等,因此在进行比较时需要注意外壳。
element.tagName
returns INPUT, etc so you need to take care of the casing when doing the comparing.
var value = ko.unwrap(valueAccessor());
你正在展开你的observable,所以在你的计算中你正在使用它的值,而不是函数本身。所以你只需要 var value = valueAccessor();
,你需要在你的计算<$中调用 ko.unwrap
c $ c>读取方法。
var value = ko.unwrap(valueAccessor());
you are unwrapping your observable so in your computed you are using its value and not the function itself. So you just need var value = valueAccessor();
and you need to call ko.unwrap
in your computed read
method.
您不仅需要格式化,而且还需要在<格式化写
方法,但你的 formatLargeNumber
只做格式方向。
You don't just need to format but you need to "unformat" in the write
method, but your formatLargeNumber
only do the format direction.
您已在同一输入上应用了值
和 largeNumber
,这使得两个绑定会干扰每个其他
You have applied value
and your largeNumber
on the same input which make the two bindings interfering with each other
不要自己编写格式代码,只需使用已经执行此操作的库: http://numeraljs.com/
Don't write the formatting code yourself just use a library which already does this like: http://numeraljs.com/
所以这是修正后的绑定版本使用numeraljs:
So here is the corrected version of your binding using numeraljs:
ko.bindingHandlers.largeNumber = {
init: function(element, valueAccessor) {
var value = valueAccessor();
var interceptor = ko.computed({
read: function() {
return numeral(ko.unwrap(value)).format('0,0');
},
write: function(newValue) {
value(numeral().unformat(newValue));
value.valueHasMutated();
}
}).extend({notify: 'always'});
if(element.tagName.toLowerCase() == 'input' )
ko.applyBindingsToNode(element, {
value: interceptor
});
else
ko.applyBindingsToNode(element, {
text: interceptor
});
}
}
并像这样使用:
<input data-bind="largeNumber: testVal">
演示 JSFiddle 。
这篇关于Knockout bindingHandler用于逗号分隔的数字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!