javascript - 用于逗号分隔数字的 Knockout bindingHandler

标签 javascript jquery knockout.js knockout-2.0

我正在使用 KnockoutJS 构建一个非常大量的数字应用程序,我希望能够格式化大数字,以便它们以逗号分隔并且看起来不错(xxx,xxx)。

正如您将从下面的 fiddle 中看到的那样,我确实通过使用简单的 RegEx 将绑定(bind)值包装在格式化函数中来实现这一点,但问题是这会覆盖输入中的值并插入 ', ' 转化为基础值(value)。

大数字在应用程序中进一步使用,因此为了防止出现 NaN 错误,我必须将数据属性分配给包含不带“,”的值的输入值,这是存储在 sessionStorage 中的值。

我觉得我的 HTML 标记不必要地膨胀了,我相信我想用 bindingHandler 实现我想要的东西是可能的,但我的绑定(bind)处理程序并不完全存在。

fiddle :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
            });
    }
}

有什么想法吗?

最佳答案

您当前的方法存在多个问题:

  • element.tagName 返回 INPUT 等,因此在进行比较时需要注意大小写。

  • var value = ko.unwrap(valueAccessor()); 您正在解包您的 observable,因此在您的计算中您使用的是它的值而不是函数本身。所以你只需要 var value = valueAccessor(); 并且你需要在计算的 read 方法中调用 ko.unwrap

  • 您不仅需要格式化,还需要在write 方法中“取消格式化”,但是您的formatLargeNumber 只做格式化方向。

  • 您已将 valuelargeNumber 应用于同一输入,这使得两个绑定(bind)相互干扰

  • 不要自己编写格式化代码,只需使用已经执行此操作的库即可:http://numeraljs.com/

所以这是使用 numeraljs 绑定(bind)的更正版本:

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 .

关于javascript - 用于逗号分隔数字的 Knockout bindingHandler,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23180385/

相关文章:

javascript - 如何为新的 Angular 项目设置 Tailwind?

javascript - 在 JavaScript 中单击按钮时将用户输入添加到列表

javascript - AJAX 重新加载按钮有时会多次添加相同的消息

javascript - 模拟点击事件以将 div 旋转为可见

javascript - 如果父级具有特定值,则希望将 CSS 类添加到子级

javascript - knockout 验证自定义规则不起作用

javascript - Knockout Observable 数组没有被观察到?

javascript - WordPress 中帖子的关联查询 - 两个问题

javascript - 函数也是对象?

c# - knockout 下拉列表数据绑定(bind)在 ajax 调用中不起作用