Knockout bindingHandler用于逗号分隔的数字 [英] Knockout bindingHandler for comma separated numbers

查看:117
本文介绍了Knockout bindingHandler用于逗号分隔的数字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆