这是a sample angular directive to prevent typing non-numeric keys (StackOverflow answer)。 我想写一些类似this fiddle的东西,在几个输入中使用is-number指令。请注意,由于我的输入中有各种不同的指令,因此我不能使用上述答案更新中建议的相同模板。
var $scope;
var app = angular.module('myapp', []);
app.controller('Ctrl', function($scope) {
$scope.myNnumber1 = 1;
$scope.myNnumber2 = 1;
});
app.directive('isNumber', function () {
return {
require: 'ngModel',
link: function (scope, element) {
scope.$watch(element.ngModel, function(newValue,oldValue) {
newValue = String(newValue);
newValue = newValue.replace('۰', '0').replace('۱', '1').replace('۲', '2').replace('۳', '3').replace('۴', '4').replace('۵', '5').replace('۶', '6').replace('۷', '7').replace('۸', '8').replace('۹', '9');
var arr = String(newValue).split("");
if (arr.length === 0) return;
if (arr.length === 1 && (arr[0] == '-' || arr[0] === '.' )) return;
if (arr.length === 2 && newValue === '-.') return;
if (isNaN(newValue)) {
element.ngModel = oldValue;
}
});
}
};
更新 请考虑我需要做一些流程来转换非英语数字等。我根据Angular_10的答案创建了a new fiddle here。现在,除了键入波斯数字的光标位置外,每件事都很好。当我键入一个波斯数字时,它被替换为英文等价数字,但光标突然跳到最后。
答案 0 :(得分:6)
以下是同一
的fiddle<强>问题强>
您引用并对给定指令进行更改的示例导致了该问题。
element ng-model
并尝试通过指令进行修改,这是不好的做法,也是指令不工作的根本原因。因为您没有更改ng-model
值,而是依次修改角度无法识别的HTML元素值。$watch
并不总是更好。<强>解决方案强>
app.directive('isNumber', function() {
return {
require: 'ngModel',
restrict: 'A',
link: function(scope, element, attr, ctrl) {
function inputValue(val) {
if (val) {
var numeric = val.replace(/[^- 0-9]/g, '');
if (numeric !== val) {
ctrl.$setViewValue(numeric );
ctrl.$render();
}
return numeric;
}
return undefined;
}
ctrl.$parsers.push(inputValue);
}
};
});
当指令需要控制器通信时,我们可以在链接功能中将Controller作为4个参数传递。从Ctrl参数中我们可以修改/查看来自控制器范围的内容。
使用一些基本的正则表达式来找出输入的输入是什么,并将其设置在控制器范围对象视图值中。
ctrl.$setViewValue(numeric); //to set the value in the respective ngModdel
ctrl.$render(); //to display the changed value
的更多信息
答案 1 :(得分:0)
我终于使用了以下指令。此伪指令转换波斯数字,并且不允许在文本框中键入任何数字。特别感谢Angular_10。我向他奖励了50个赏金。
app.directive('fixPersianAndNoNumberInput', function ($filter) {
return {
require: 'ngModel',
restrict: 'EA',
link: function (scope, element, attr, controller) {
function inputValue(val) {
if (val) {
let numeric = parseInt(String(val).replace('۰', '0').replace('۱', '1').replace('۲', '2').replace('۳', '3').replace('۴', '4').replace('۵', '5').replace('۶', '6').replace('۷', '7').replace('۸', '8').replace('۹', '9').replace(' ', '000').replace(/[^- 0-9]/g, ''));
if (numeric !== val) {
controller.$setViewValue(numeric);
controller.$render();
let value;
let updateOn, debounce;
if (controller.$options) {
if (controller.$options.getOption) {
updateOn = controller.$options.getOption('updateOn');
debounce = controller.$options.getOption('debounce');
} else {
updateOn = controller.$options.updateOn;
debounce = controller.$options.debounce;
}
}
if (updateOn === 'blur' || debounce) {
value = controller.$viewValue;
for (let i = controller.$parsers.length - 1; i >= 0; i--) {
value = controller.$parsers[i](value);
}
} else {
value = controller.$$rawModelValue;
}
for (let j = controller.$formatters.length - 1; j >= 0; j--) {
value = controller.$formatters[j](value);
}
controller.$viewValue = value;
controller.$render();
}
return numeric;
}
return undefined;
}
controller.$parsers.push(inputValue);
controller.$formatters.push((value) => {
if ([undefined, null, ''].indexOf(value) === -1) {
return $filter('currency')(value, '', 0);
}
return value;
});
}
};
});