我正在尝试从链接函数向自定义指令添加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时,它正在工作。
答案 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);
}
}
}
})
但另一方面,我没有看到使用ng-class
指令添加和删除类的代码有任何优势。当您设置表单控件的有效性时,隐含地您要添加和删除ng-valid-compare-to
(有效)&amp; ng-invalid-compare-to
(无效)类。因此,没有必要创建额外的开销来让ng-class
逻辑再次放置相同的东西。