链接函数中的角$ compile给出错误"RangeError:超出最大调用堆栈大小". [英] Angular $compile in link function gives an error "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和link函数.从编译功能中,您需要添加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.
这篇关于链接函数中的角$ compile给出错误"RangeError:超出最大调用堆栈大小".的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!