Knockout.js扩展与拦截器的值绑定 [英] Knockout.js Extending value binding with interceptor

查看:144
本文介绍了Knockout.js扩展与拦截器的值绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 computed observable. It basically extends the default value binding to include an interceptor that will format/sanitize/validate input before written/read.

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/

jsFiddle example: http://jsfiddle.net/6wxb5/1/

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

Am i missing something? I've seen this method used everywhere, but it doesn't seem to fully work. The read function seems completely useless as it doesn't get used at all.., and in the write function, entering "23.0000" changes the written value to 23, but the textbox values do not update.

推荐答案

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

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.

一个选项是应用 init 函数中的值绑定并跳过更新函数如:

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

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

这篇关于Knockout.js扩展与拦截器的值绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆