我正在尝试为电话号码格式创建一个挖空扩展。当我第一次输入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" />