Knockout.js Extending value binding with interceptor

后端 未结 1 1181
别跟我提以往
别跟我提以往 2020-12-13 22:57

This seems to be a common approach to sanitizing/validating/formatting data with knockout when binding to an input field, it creates a reusable custom binding that uses a co

相关标签:
1条回答
  • 2020-12-13 23:14

    The issue comes from the update portion of your custom binding. This part will update the field based on the original model value. So, the event handler attached in the init will send the new value through your writeable computed, but the updating of the field actually happens in the update.

    One option is to apply the value binding from your init function and skip the update function like:

    ko.bindingHandlers.amountValue = {
      init: function (element, valueAccessor, allBindingsAccessor) {
        var underlyingObservable = valueAccessor();
    
        var interceptor = ko.computed({
          read: function () {
            // this function does get called, but it's return value is not used as the value of the textbox.
            // the raw value from the underlyingObservable, or the actual value the user entered is used instead, no   
            // dollar sign added. It seems like this read function is completely useless, and isn't used at all
            return "$" + underlyingObservable();
          },
    
          write: function (newValue) {
            var current = underlyingObservable(),
                valueToWrite = Math.round(parseFloat(newValue.replace("$", "")) * 100) / 100;
    
            if (valueToWrite !== current) {
              // for some reason, if a user enters 20.00000 for example, the value written to the observable
              // is 20, but the original value they entered (20.00000) is still shown in the text box.
              underlyingObservable(valueToWrite);
            } else {
              if (newValue !== current.toString())
                underlyingObservable.valueHasMutated();
            }
          }
        });
    
          ko.applyBindingsToNode(element, { value: interceptor });
      }
    };
    

    Updated fiddle: http://jsfiddle.net/rniemeyer/Sr8Ev/

    0 讨论(0)
提交回复
热议问题