繁体   English   中英

Knockout.js扩展与拦截器的值绑定

[英]Knockout.js Extending value binding with interceptor

这似乎是在绑定到输入字段时使用knockout清理/验证/格式化数据的常用方法,它创建了一个使用计算的observable的可重用自定义绑定。 它基本上扩展了默认值绑定,以包括一个拦截器,它将在写入/读取之前格式化/清理/验证输入。

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 is still used, 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.bindingHandlers.value.init(element, function () { return interceptor }, allBindingsAccessor);
  },

  update: ko.bindingHandlers.value.update
};

jsFiddle示例: http//jsfiddle.net/6wxb5/1/

我错过了什么吗? 我已经看到这种方法在任何地方使用,但它似乎没有完全奏效。 read函数似乎完全无用,因为它根本没有被使用..在write函数中,输入“23.0000”会将写入值更改为23,但文本框值不会更新。

问题来自自定义绑定的update部分。 此部分将根据原始模型值更新字段。 因此, init附加的事件处理程序将通过可写入的计算机发送新值,但实际上update时会update字段。

一个选项是从init函数应用值绑定并跳过update函数,如:

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

更新小提琴: http//jsfiddle.net/rniemeyer/Sr8Ev/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM