【问题标题】:Knockout.js Extending value binding with interceptorKnockout.js 使用拦截器扩展值绑定
【发布时间】:2012-09-20 13:00:28
【问题描述】:

这似乎是一种在绑定到输入字段时使用淘汰赛清理/验证/格式化数据的常用方法,它创建了一个可重用的自定义绑定,该绑定使用计算的 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,但文本框的值不会更新。

【问题讨论】:

    标签: javascript knockout.js knockout-2.0 knockout-validation


    【解决方案1】:

    问题来自自定义绑定的update 部分。这部分将根据原始模型值更新字段。因此,init 中附加的事件处理程序将通过您的可写计算发送新值,但该字段的更新实际上发生在 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/

    【讨论】:

    • 谢谢,这很令人沮丧;)
    猜你喜欢
    • 2012-08-18
    • 2014-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-26
    • 2019-03-11
    • 1970-01-01
    相关资源
    最近更新 更多