我在KnockoutJS中构建了一个数量非常繁重的应用程序,我希望能够对大数字进行格式化,以便它们以逗号分隔并且很好看(xxx,xxx)。 / p>
正如您从下面的小提琴中看到的那样,我确实通过使用简单的RegEx将绑定值包装在格式化函数内部,但问题是这会覆盖输入中的值并插入','进入潜在价值。
在应用程序的下方使用了大数字,因此为了防止NaN错误,我必须将数据属性分配给包含没有','的值的输入值。这是存储在sessionStorage中的值。
我觉得我的HTML标记不知不觉地膨胀了,并且相信我想通过bindingHandler实现的目标是可能的,但我的绑定处理程序并不存在。
小提琴: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
});
}
}
有什么想法吗?
答案 0 :(得分:14)
您当前的方法存在多个问题:
element.tagName
返回INPUT等,因此在进行比较时需要注意外壳。
var value = ko.unwrap(valueAccessor());
你正在展开你的observable,所以在你的计算中你正在使用它的值,而不是函数本身。因此,您只需要var value = valueAccessor();
,并且需要在计算出的ko.unwrap
方法中调用read
。
您不仅需要格式化,而且需要在write
方法中“取消格式化”,但您的formatLargeNumber
仅执行格式化方向。
您已将value
和largeNumber
应用于相同的输入,这使得两个绑定相互干扰
不要自己编写格式代码,只需使用已经执行此操作的库:http://numeraljs.com/
所以这是使用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。