Angular指令:只允许数字

Ahm*_*mad 5 javascript angularjs angularjs-directive

这是一个示例angular指令,用于防止键入非数字键(StackOverflow应答).我想写一些类似这个小提琴的东西,在几个输入中使用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;
                }
            });
        }
   };
Run Code Online (Sandbox Code Playgroud)

更新: 请考虑我需要做一些流程来转换非英语数字等.我根据Angular_10的答案创造了一个新的小提琴.现在,除了键入波斯数字的光标位置外,每件事都很好.当我键入一个波斯数字时,它被替换为英文等效数字,但光标突然跳到最后.

ngC*_*der 6

好 !看看你的要求我已经采取了自由并编写了更多的定制指令.

这是同样的小提琴

问题

您引用并对给定指令进行更改的示例导致了该问题.

  1. 你的$ scope变量名在HTML/JS中是错误的($ scope.myNnumber1 = 1; $ scope.myNnumber2 = 1;在JS和HTML中它是ng-model ="myNumber1")
  2. 您正在访问element ng-model并尝试通过指令修改它,这是不好的做法,也是指令不工作的根本原因.因为您没有更改ng-model值,而是修改了角度无法识别的HTML元素值.
  3. $watch出于性能考虑,更多地使用in指令并不总是优选的.

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);
        }
    };

});
Run Code Online (Sandbox Code Playgroud)

当指令需要控制器通信时,我们可以在链接函数中将Controller作为4个参数传递.从Ctrl参数中我们可以修改/查看控制器范围内的事物.

使用一些基本的正则表达式来找出输入的输入是什么,并将其设置在控制器范围对象视图值中.

ctrl.$setViewValue(numeric); //to set the value in the respective ngModdel
ctrl.$render(); //to display the changed value
Run Code Online (Sandbox Code Playgroud)

有关$ setViewValue的更多信息


Ahm*_*mad 0

我最终使用了以下指令。该指令转换波斯语数字,并且不允许在文本框中输入任何数字。特别感谢 Angular_10。为了感谢他的帮助,我悬赏了 50 美元。

\n\n
app.directive('fixPersianAndNoNumberInput', function ($filter) {\n    return {\n        require: 'ngModel',\n        restrict: 'EA',\n        link: function (scope, element, attr, controller) {\n            function inputValue(val) {\n                if (val) {\n                    let numeric = parseInt(String(val).replace('\xdb\xb0', '0').replace('\xdb\xb1', '1').replace('\xdb\xb2', '2').replace('\xdb\xb3', '3').replace('\xdb\xb4', '4').replace('\xdb\xb5', '5').replace('\xdb\xb6', '6').replace('\xdb\xb7', '7').replace('\xdb\xb8', '8').replace('\xdb\xb9', '9').replace(' ', '000').replace(/[^- 0-9]/g, ''));\n                    if (numeric !== val) {\n                        controller.$setViewValue(numeric);\n                        controller.$render();\n                        let value;\n                        let updateOn, debounce;\n                        if (controller.$options) {\n                            if (controller.$options.getOption) {\n                                updateOn = controller.$options.getOption('updateOn');\n                                debounce = controller.$options.getOption('debounce');\n                            } else {\n                                updateOn = controller.$options.updateOn;\n                                debounce = controller.$options.debounce;\n                            }\n                        }\n                        if (updateOn === 'blur' || debounce) {\n                            value = controller.$viewValue;\n                            for (let i = controller.$parsers.length - 1; i >= 0; i--) {\n                                value = controller.$parsers[i](value);\n                            }\n                        } else {\n                            value = controller.$$rawModelValue;\n                        }\n                        for (let j = controller.$formatters.length - 1; j >= 0; j--) {\n                            value = controller.$formatters[j](value);\n                        }\n                        controller.$viewValue = value;\n                        controller.$render();\n                    }\n                    return numeric;\n                }\n                return undefined;\n            }\n\n            controller.$parsers.push(inputValue);\n            controller.$formatters.push((value) => {\n                if ([undefined, null, ''].indexOf(value) === -1) {\n                   return $filter('currency')(value, '', 0);\n                }\n                return value;\n            });\n        }\n    };\n});\n
Run Code Online (Sandbox Code Playgroud)\n