【发布时间】:2016-03-12 12:35:39
【问题描述】:
我正在尝试解决我在使用自定义 Angular 指令和 Chrome 的自动填充时注意到的错误。我已经为电话号码字段编写了指令。该指令在电话号码字段中添加破折号“-”(因此用户在输入他们的号码时不必添加任何破折号)。
指令,如下所示
app.directive("phoneNumberValidator", function () {
return {
require: "ngModel",
restrict: "A",
link: function (scope, elem, attrs, ctrl) {
var domElement = elem[0]; // Get DOM element
var phoneNumberRegex = new RegExp("\\d{3}\\-\\d{3}\\-\\d{4}"); // Phone number regex
var cursorIndex; // Index where the cursor should be
// Create a parser to alter and validate if our
// value is a valid phone number
ctrl.$parsers.push(function (value) {
// If our value is non-existent, we return undefined
// WHY?: an angular model value should be undefined if it is empty
if (typeof value === "undefined" || value === null || value == "") {
ctrl.$setValidity('invalidFormat', true); // No invalid format if the value of the phone number is empty
return undefined;
}
// PARSER LOGIC
// =compare our value to a modified value after it has
// been transformed into a "nice" phone number. If these
// values are different, we set the viewValue to
// the "nice" phone number. If these values are the same,
// we render the viewValue (aka. "nice" phone number)
var prevValue, nextValue;
prevValue = value;
nextValue = value.replace(/[\D]/gi, ""); // Strip all non-digits
// Make the "nice" phone number
if (nextValue.length >= 4 && nextValue.length <= 6) {
nextValue = nextValue.replace(/(\d{3})(\d{3})?/, "$1-$2");
} else if (nextValue.length >= 7 && nextValue.length <= 10) {
nextValue = nextValue.replace(/(\d{3})(\d{3})(\d{4})?/, "$1-$2-$3");
}
// Save the correct index where the custor should be
// WHY?: we do this here because "ctrl.$render()" shifts
// the cursor index to the end of the phone number
cursorIndex = domElement.selectionStart;
if (prevValue != nextValue) {
ctrl.$setViewValue(nextValue); // *Calling this function will run all functions in ctrl.$parsers!
} else {
ctrl.$render(); // Render the new, "nice" phone number
}
// If our cursor lands on an index where a dash "-" is,
// move it up by one
if (cursorIndex == 4 || cursorIndex == 8) {
cursorIndex = cursorIndex + 1;
}
var valid = phoneNumberRegex.test(value); // Test the validity of our phone number
ctrl.$setValidity('invalidFormat', valid); // Set the validity of the phone number field
domElement.setSelectionRange(cursorIndex, cursorIndex); // Assign the cursor to the correct index
return value; // Return the updated value
});
}
}
});
问题在于 Chrome 自动填充此字段。通过使用 Batarang 扩展 (https://chrome.google.com/webstore/detail/angularjs-batarang/ighdmehidhipcmcojjgiloacoafjmpfk?hl=en),我可以看到页面上正在使用的范围值。
当我有 Chrome autofill 我的电话号码字段,值为“1234567899”时,我的$scope Angular 电话字段的值为 1234567899(它应该是:“123-546- 7899")。
在我的指令中放置一个断点将使我看到当 Chrome 自动填充我的字段时该指令确实在我的浏览器中运行,但 $scope.PhoneNumber 字段的值是 1234567899,而不是 123-456-7899。 简而言之,自动填充时 $viewModel 会正确更新,但 $modelValue 不会
Chrome 自动填充电话字段后,我能否以编程方式更改 $modelValue 以反映应保留在 $scope.PhoneNumber 中的正确值?
【问题讨论】:
-
您能否在 plnkr.co 中添加一个可运行的示例?
-
是的,我会为这个问题找一个人
-
添加了一个 plunkr,在浏览链接之前,您必须有一个不包含破折号的自动填充电话号码
标签: javascript angularjs google-chrome