Knockout bindingHandler for comma separated number

2019-05-31 04:08发布

问题:

I needed to create a Knockout bindingHandler which would format the amount to comma separated numbers. After a little searching I found the solution here (Thanks to @nemesv for the solution) which uses http://numeraljs.com/ for the conversion.

the binder is as follows:

ko.bindingHandlers.formatMoney = {
  init: function(element, valueAccessor) {

    var value = valueAccessor();

    var interceptor = ko.computed({
        read: function() {
            return numeral(ko.unwrap(value)).format('0,0.00');
        },
        write: function(newValue) {
            if($.trim(newValue) == '')
                value("0");
            else
                value(numeral().unformat(newValue));
        }
    }).extend({ notify: 'always' });

    if(element.tagName.toLowerCase() == 'input' )
        ko.applyBindingsToNode(element, {
            value: interceptor
        });
    else
        ko.applyBindingsToNode(element, {
            text: interceptor
        });
  }
}

I used it and it works perfectly in normal cases. But I need to fix it when using it with textbox.

The issue is that an observable is being used which are normally only notified if the value actually changed. So the actual formater is applied if I type a different value every time. So for example

  • if I type 1234 for the first time and textbox loses focus, it gets converted to 1,234.00.
  • now if you type 1234 again in the textbox. it does not work and the binder's read method is not called.

What do I have to do to make the interceptor's read method fire everytime even if the observable has the same value.?

Sample Fiddle: http://jsfiddle.net/vEcSq/4/

Thanks.

回答1:

You can use the valueHasMutated function on the observable to alert subscribers that it has changed, even if it hasn't. In the write function on the interceptor, add the following line as the last line of the function.

value.valueHasMutated();

I have updated your jsfiddle with the call and it seems to be working correctly.