前言
我对 AngularJS 一无所知。我以前从未使用过它。这是我第一次看到它。我不知道它有什么作用。它似乎所做的只是添加一个巨大的抽象层来混淆代码,并证明增加 IT 支出给能够看穿这种混淆的“内部人员”是合理的。如果没有 AngularJS,你的任务会简单得多。但是,正如我所说,我不知道 AngularJS 是什么,也不知道它的作用,所以我可能是错的。
基本解决方案
报告行为的原因是每次用户键入任何内容时,您的脚本都会覆盖 <input> 值。通常和基本的解决方案是在覆盖之前存储插入符号位置 (element.val(...)):
var caretPosition = element[0].selectionStart;
...并在之后立即恢复:
element[0].focus(); element[0].setSelectionRange(caretPosition, caretPosition);
您的脚本确实包含一个插入符号处理代码的存根,但它实际上什么也没做,它只是通过有意将插入符号移动到字符串的末尾来重复其自己的意外行为。这种毫无意义的行为似乎是对任何重用代码来编写自己的插入符号处理代码的人的暗示。用我的代码替换那个存根。
现场示例
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {$scope.name = 'Phone Number';});
app.directive('abcXyz', function($filter) {
var mobileFilter, mobileReverse;
mobileFilter = $filter('mobileFilter');
mobileReverse = $filter('mobileReverse');
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attrs, modelCtrl) {
var formatter, parser;
parser = function(value) {
var formatted;
formatted = mobileReverse(value);
/* solution */ var caretPosition = element[0].selectionStart;
/* solution */ if (caretPosition === 4) caretPosition += 3;
/* solution */ if (caretPosition === 10) ++caretPosition;
element.val(mobileFilter(formatted));
/* solution */ element[0].selectionStart = element[0].selectionEnd = caretPosition;
return formatted;
};
modelCtrl.$formatters.push(formatter);
return modelCtrl.$parsers.unshift(parser);
}
};
});
app.filter('mobileFilter', function() {
return function(value) {
var len, val;
if (!value) return;
val = value.toString().replace(/\D/g, "");
len = val.length;
if (len < 4) return val;
else if (3 < len && len < 7)
return "(" + (val.substr(0, 3)) + ") " + (val.substr(3));
else if (len > 6)
return "(" + (val.substr(0, 3)) + ") " + (val.substr(3, 3)) +
"-" + (val.substr(6, 4));
return value;
}
});
app.filter("mobileReverse", () => value => !!value && value.replace(/\D/g, "")
.substr(0, 10));
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js">
</script>
<html ng-app="plunker">
<body ng-controller="MainCtrl">
<p>{{name}}!</p>
<input type="tel" abc-xyz ng-model="formData.Phone" name="worktype"
maxlength="14" required="required" ng-pattern="(/[0-9-()]*[1-9][0-9-()]*/);"
autoComplete="off">
</body>
</html>
完整的解决方案
基本解决方案是一种改进,但它仍然不完美。退格失败。用户有时可以添加字母或删除强制性破折号或括号。您似乎需要一个复杂的插入符号处理程序,它能够识别退格、过滤器,而不是一个,而是 两个 最后插入符号位置。我已经在基本示例中包含了简单的过滤器意识:
if (caretPosition === 4) caretPosition += 3;
if (caretPosition === 10) ++caretPosition;
但这还不够。在这一点上,我无法向您提供完整的插入符号处理程序,但至少让我向您展示如何在 AngularJS 代码中包含退格意识:
- 将属性
ng-keydown="registerBackspace($event)"添加到HTML标签<input type="tel">。
- 用这个电话代替你的
app.controller()电话:
app.controller('MainCtrl', function($scope) {
$scope.name = '电话号码';
$scope.registerBackspace = event => window.phoneBackspace = event.keyCode == = 8;
});
- 现在您有一个全局变量
window.phoneBackspace,它指示在电话输入字段中按下的最后一个键是否为退格键(true 或false)。
我不喜欢全局变量,但我对 AngularJS 不知道如何使用它自己的函数来传递这些信息(也不知道它是否允许这样做)。
最后的话
如果您认为版主是白痴,请投票。
文学