【问题标题】:Knockout js bindingHandlers extension not updating text input control on some character inputKnockout js bindingHandlers扩展不更新某些字符输入的文本输入控件
【发布时间】:2016-06-09 00:47:24
【问题描述】:

我正在尝试为电话号码格式创建淘汰赛扩展。 第一次输入 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);
            }
        }

【问题讨论】:

    标签: javascript knockout.js


    【解决方案1】:

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

    当你输入你的第一个数字时,你将 observable 设置为"213-913-9090"。每当&lt;input&gt; 模糊时,您都会重新评估该值。现在这是关键:

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

    您可以快速解决两个问题:

    • 在你用相同的值设置 observable 之后调用observable.notifySubscribers,或者
    • 使用.extend({ notify: 'always' }) 扩展user.phone

    或者,您可以使用自定义扩展器尝试不同的方法,例如 this example (Example 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" />

    【讨论】:

    • 效果很好。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-17
    • 1970-01-01
    • 1970-01-01
    • 2017-01-16
    • 2020-06-13
    • 1970-01-01
    相关资源
    最近更新 更多