Knockout js bindingHandlers 扩展不更新某些字符输入的文本输入控件



我正在尝试为电话号码格式创建一个挖空扩展。当我第一次输入2139139090到213-913-9090时,电话号码的格式正确。紧接着,如果我从数字中删除连字符 (-),则不会在文本控件中格式化它。但是,如果我将格式化的值从 js 代码记录到控制台,它会显示为格式化。空格的行为相同,+1 类似于特殊字符。如果我更改数字中的任何数字,则所有格式都可以正常工作。

<input type="text" class="form-control" id="userform-phone" data-bind="textInputPhone:user.phone" /> 

ko.bindingHandlers.textInputPhone = {
            init: function (element, valueAccessor) {
                $(element).on('blur', function () {
                    var inputvalue = $(element).val().trim();
                    var observable = valueAccessor();
                    if (inputvalue) {
                        var regexstring = /^(?:+?1)?(?[- .]?(d{3}))?[- .]?(d{3})[- .]?(d{4})([-. ]?[a-zA-z].*)?$/gm
                        var phoneformat = '$1-$2-$3$4';
                        var formattedPhoneNumber = inputvalue.replace(regexstring, phoneformat);
                        observable(formattedPhoneNumber);
                    } else {
                        observable('');
                    }
                });
            },
            update: function (element, valueAccessor) {
                var valueUnwrapped = ko.utils.unwrapObservable(valueAccessor());
                $(element).val(valueUnwrapped);
            }
        }

当你设置一个ko.observable时,它会检查新值是否与它已经持有的值不同。如果值相同,则不会通知任何订阅者。

输入第一个数字时,将可观察量设置为 "213-913-9090" 。每当<input>模糊时,您都会重新评估该值。现在这里有一个问题:

如果只更改空格,则编辑前后的结果将完全相同。这意味着不会触发您的update,并且永远不会调用.val(valueUnwrapped)

您可以进行两个快速修复:

  • 在将可观察量设置为相同值后调用observable.notifySubscribers,或者
  • 使用.extend({ notify: 'always' })扩展user.phone

或者,您可以使用自定义扩展器尝试不同的方法,如本示例(示例 1)所示。

一个快速修复的示例:

ko.bindingHandlers.textInputPhone = {
  init: function(element, valueAccessor) {
    $(element).on('blur', function() {
      var inputvalue = $(element).val().trim();
      var observable = valueAccessor();
      var newValue = '';
      if (inputvalue) {
        var regexstring = /^(?:+?1)?(?[- .]?(d{3}))?[- .]?(d{3})[- .]?(d{4})([-. ]?[a-zA-z].*)?$/gm
        var phoneformat = '$1-$2-$3$4';
        var formattedPhoneNumber = inputvalue.replace(regexstring, phoneformat);
        newValue = formattedPhoneNumber;
      }
      // Option 1: notify explicitly
      if (observable.peek() === newValue) {
        observable.notifySubscribers(newValue);
      } else {
        observable(newValue);
      }
    });
  },
  update: function(element, valueAccessor) {
    var valueUnwrapped = ko.utils.unwrapObservable(valueAccessor());
    $(element).val(valueUnwrapped);
  }
}
ko.applyBindings({
  user: {
    phone: ko.observable("") //.extend({notify: 'always'}) // Option 2
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input data-bind="textInputPhone:user.phone" />

相关内容

最新更新