链接函数中的 Angular $compile 给出错误“RangeError: Maximum call stack size exceeded" [英] Angular $compile in link function gives an error "RangeError: Maximum call stack size exceeded"

查看:40
本文介绍了链接函数中的 Angular $compile 给出错误“RangeError: Maximum call stack size exceeded"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to add a ng-class attribute to a custom directive from the link function. But when using compile function after adding the ng-class attribute, It throws an error like "RangeError: Maximum call stack size exceeded"

请看下面的代码

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 时它正在工作.

It is working when I add the ng-class directly in the html.

推荐答案

$compile(ele)(scope); 编译指令元素中的一行,这将导致无限调用编译你的指令代码循环,这就是为什么它会给出 RangeError: Maximum call stack size exceeded" 错误.

$compile(ele)(scope); line in compiling directive element, which will leads to call compile your directive code in infinite loop, that's why it is giving "RangeError: Maximum call stack size exceeded" error.

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

Ideally you should use combination of compile and link function together. From compile function you need to add ng-class attribute & then remove the directive attribute to avoid directive element to compile indefinitely. Then compile your directive element with scope from directive link function.

代码

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

类似的答案

此处演示

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

But the other thing, I don't see any advantage with your code of adding and removing class using ng-class directive. As you are setting validity of your form control, implicitly you are adding and removing ng-valid-compare-to(on valid) & ng-invalid-compare-to(on invalid) class. So there is no need to create extra overhead to have ng-class logic to putting same thing again.

这篇关于链接函数中的 Angular $compile 给出错误“RangeError: Maximum call stack size exceeded"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆