2017-04-05 71 views
0

我想通过自定义指令将“ng-pattern”指令添加到输入元素。我不想直接在模板中执行它,但看起来我陷入了无限循环。Angular指令编译:“RangeError:超出最大调用堆栈大小”

我试着先设置'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; 
        }); 
       } 
      }; 
     } 
    }; 
} 

回答

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> 

这里是一个plunker:https://plnkr.co/edit/X6Fi0tnjBXKKhbwH0o2q?p=preview

希望它能帮助!

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); 
相关问题