链接函数中的Angular $ compile给出错误“RangeError:超出最大调用堆栈大小”

时间:2016-01-15 06:08:43

标签: angularjs angularjs-directive

我正在尝试从链接函数向自定义指令添加ng-class属性。但是在添加ng-class属性后使用编译功能时,会抛出类似“RangeError:超出最大调用堆栈大小”的错误

请参阅以下代码

MyApp.directive('twinField',function($compile){
return {
    restrict:'A',
    require:'ngModel',
    scope:{
        fval:'='
    },
    link:function(scope,ele,attr,ctrl){
        ctrl.$validators.compareTo=function(val){
            //alert(scope.fval)
            return scope.fval==val
        }
        scope.$watch('fval', function(newValue, oldValue, scope) {
            ctrl.$validate()
        });
        ele.attr("ng-class","addForm.cpassword.$error.compareTo?'errorpswd':''")//=""
        $compile(ele)(scope);
    }
}

})

当我直接在html中添加ng-class时,它正在工作。

1 个答案:

答案 0 :(得分:7)

编译指令元素中的

$compile(ele)(scope);行,这将导致在无限循环中调用编译指令代码,这就是它给出“RangeError: Maximum call stack size exceeded”错误的原因。

理想情况下,您应该结合使用编译和链接功能。从编译功能,您需要添加ng-class属性&然后删除指令属性以避免指令元素无限编译。然后使用指令链接函数的范围编译指令元素。

<强>代码

myApp.directive('twinField', function($compile) {
  return {
    restrict: 'A',
    require: 'ngModel',
    scope: {
      fval: '='
    },
    compile: function(tElement, tAttrs) {
      console.log(tElement)

      tElement.removeAttr('twin-field');

      return function(scope, ele, attr, ctrl) {
        ele.attr("ng-class", "addForm.cpassword.$error.compareTo?'errorpswd':''");
        ele.attr("test", "{{test}}':''");
        var compileFn = $compile(ele);
        ctrl.$validators.compareTo = function(val) {
          //alert(scope.fval)
          return scope.fval == val
        }
        scope.$watch('fval', function(newValue, oldValue, scope) {
          ctrl.$validate()
        });
        compileFn(scope);
      }
    }
  }
})

Similar answer

Demo here

但另一方面,我没有看到使用ng-class指令添加和删除类的代码有任何优势。当您设置表单控件的有效性时,隐含地您要添加和删除ng-valid-compare-to(有效)&amp; ng-invalid-compare-to(无效)类。因此,没有必要创建额外的开销来让ng-class逻辑再次放置相同的东西。