如何向自定义验证器指令传递动态属性?
解决AngularJS指令中获取属性表达式返回值的问题
嗨,这个问题我太熟悉了!你现在遇到的核心问题是:当你通过attributes对象获取模板里的属性值时,拿到的只是字符串形式的表达式,而不是这个表达式执行后的结果。就像你看到的,attributes.myValidation返回的是"$ctrl.getmyAtt()"这个字符串,而不是getmyAtt()方法返回的"blah"。
下面给你两种实用的解决方案:
方案一:用$eval直接执行表达式
AngularJS的作用域提供了$eval方法,可以帮你在当前作用域下解析并执行这个字符串表达式,直接拿到返回值。修改你的指令link函数即可:
return { restrict: 'A', require: 'ngModel', link: (scope, element, attributes, ngModel) => { // 用$eval执行属性里的表达式 const myAttrib = scope.$eval(attributes.myValidation); console.log(myAttrib); // 现在会输出预期的"blah" // 后续的自定义验证逻辑... } }
因为你的组件用了$ctrl作为控制器别名,而指令的作用域会继承组件的隔离作用域,所以$eval能正确识别$ctrl.getmyAtt()这个表达式并执行。
方案二:用$watch监听表达式的动态变化
如果getmyAtt()的返回值可能会随着数据变化而改变,你需要让验证器能响应这种变化,这时候可以用$watch来监听表达式的结果:
return { restrict: 'A', require: 'ngModel', link: (scope, element, attributes, ngModel) => { // 监听表达式的变化,每次值更新都会触发回调 scope.$watch(attributes.myValidation, (newValue) => { const myAttrib = newValue; console.log(myAttrib); // 每次值变化都会输出最新结果 // 在这里更新你的验证逻辑,确保验证状态同步 }); } }
这种方式适合需要动态更新验证规则的场景,比如根据用户操作改变验证的参考值。
小提示
要确保你的指令作用域能正确访问到$ctrl对应的控制器,AngularJS组件默认是隔离作用域,只要指令是用在组件模板内部,作用域继承关系是没问题的,不用额外配置作用域。
内容的提问来源于stack exchange,提问作者solar apricot
相关产品推荐
相关产品推荐

