Angular指令编译:“RangeError:超出最大调用堆栈大小”

时间:2017-04-05 19:08:39

标签: angularjs angularjs-directive

我想通过自定义指令向输入元素添加'ng-pattern'指令。我不想直接在模板中这样做,但看起来我正处于一个无限循环中。

我尝试先设置'html'并在(Angular compile in directive seems to go into infinite loop)之后编译元素,但范围未定义。我不知道它是否与替换元素的内容有关。

我应该创建一个新范围吗?我错过了什么吗?

提前致谢!

                    var myHtml = iElem[0].outerHTML;
                    iElem.replaceWith(myHtml);
                    var compiledElement = $compile(iElem)(iElem.scope());

HTML:

<input type="text" ng-model="personal.testNumber_string" my-model="personal.testNumber" dot-to-comma>

指令:

function dotToCommaConverter($compile) {
    return {
        require: 'ngModel',
        restrict: 'A',
        scope: {
            myModel: '='
        },
        controllerAs: 'dot2Comma',

        controller: function($scope) {

            this.myModel = $scope.myModel;
        },


        compile: function(tElem, tAttrs) {

            return {
                pre: function(scope, iElem, iAttrs) {


                },
                post: function(scope, iElem, iAttrs, modelCtrl) {

                    iElem.attr('ng-pattern', '/^-?[0-9]+(?:\,[0-9]+)?$/');
                    var compiledElement = $compile(iElem)(iElem.scope());
                    iElem.replaceWith(compiledElement);


                    modelCtrl.$setViewValue(String(scope.dot2Comma.myModel).replace('.', ','));
                    modelCtrl.$render();


                    modelCtrl.$parsers.push(function(inputValue) {

                        var transformedInput = inputValue.replace(/[^0-9,.-]/g, '');
                        transformedInput = transformedInput.replace('.', ',');
                        transformedInput = transformedInput.replace(' ', '');

                        if (transformedInput !== inputValue) {

                            modelCtrl.$setViewValue(transformedInput);
                            modelCtrl.$render();
                        }

                        if (!isNaN(Number(transformedInput.replace(',', '.')))) {
                            scope.myModel = Number(transformedInput.replace(',', '.'));
                        } else {
                            scope.myModel = undefined;
                        }

                        return transformedInput;
                    });
                }
            };
        }
    };
}

2 个答案:

答案 0 :(得分:0)

这是一个示例指令,用文本框中的逗号替换点:

<强>的script.js

angular.module('app', []);

angular.module('app')
 .controller('ExampleController', ['$scope', function($scope) {
   $scope.my = { number: '123.456' };
 }]);

 angular.module('app')
 .directive('dotToComma', function() {
   return {
    restrict: 'A',
        link: function (scope, element, attrs) {
            scope.$watch(attrs.ngModel, function (value) {
                var newValue = value.replace('.', ',');
                element.val(newValue);
            });
        }
   }
 });

<强>的index.html

<html lang="en" ng-app="app">
<head>
  <meta charset="utf-8">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
  <script src="script.js"></script>
</head>

<body>
    <form ng-controller="ExampleController">

    <p>scope.my.number = {{my.number}}</p>

    <label>In this textbox, dots will automatically be replaced with commas, even if you change its value :</label>
    <input type="text" ng-model="my.number" dot-to-comma>
 </form>
</body>
</html>

这是一个掠夺者:https://plnkr.co/edit/X6Fi0tnjBXKKhbwH0o2q?p=preview

希望它有所帮助!

答案 1 :(得分:0)

我需要在重新编译之前从Html内容中删除我自己的指令,这是造成无限循环的原因。

                    iElem.removeAttr('dot-to-comma');
                    iElem.attr('ng-pattern', '/^-?[0-9]+(?:\,[0-9]+)?$/');
                    iElem.attr('ng-blur', 'dot2Comma.myBlurFunction()');

                    var compiledElement = $compile(iElem)(scope);
                    iElem.replaceWith(compiledElement);