AngularJS指令问题:创建前检查HTML绑定及翻译绑定失效处理
AngularJS 相关问题解答
问题1:创建directive前如何检查HTML绑定?
在写自定义指令前,我习惯先把绑定逻辑验证清楚,避免后续踩坑,分享几个实用的检查方法:
- 先在普通元素上测试绑定效果:把你要用到的表达式、过滤器先放到普通的
<div>、<p>或者原生<select>里,比如要测试translate过滤器,就先写个<p>{{'test.key'|translate}}</p>,确认翻译服务能正常工作,排除是工具本身的问题。 - 验证数据和作用域的可用性:在父控制器里用
console.log($scope)打印作用域,检查你要绑定的变量(比如months)是否已经正确加载,有没有异步数据延迟的情况。如果是异步获取的数据,要确保在数据返回后再渲染指令。 - 用调试工具排查:安装AngularJS Batarang插件,打开浏览器开发者工具的Angular面板,可以直接查看元素对应的作用域,检查绑定的表达式有没有被正确解析,变量值是否符合预期。
- 提前确认作用域传递规则:如果你的指令会用到隔离作用域,先搞清楚
@、=、&这几种绑定方式的区别,在普通元素上模拟父作用域到子作用域的传递,确认变量能正常访问。
问题2:自定义select-box指令内的translate绑定不生效,无法修改指令的解决办法
你遇到的这种情况,大概率是因为自定义指令没有编译内部的HTML内容,导致AngularJS的插值和过滤器没被处理。既然不能修改指令本身,这里有几个可行的 workaround:
方法1:提前在父作用域处理翻译值
在父控制器里先把翻译好的文本准备好,然后直接在HTML里使用这个变量:
// 父控制器代码 angular.module('yourApp').controller('YourController', function($scope, $filter) { $scope.defaultMonthText = $filter('translate')('dcl-spa.components.claim-and-link.month.mm'); });
对应的HTML:
<custom-select-box id="month" model="month" model-required model-name="month" options="month.value as month.name for month in months" aria-label="{{month.name}}"> <option value="">{{defaultMonthText}}</option> </custom-select-box>
这样父作用域已经完成了翻译,指令里的<option>直接用现成的文本,就不会显示原始键值了。
方法2:用辅助指令手动编译内部内容
写一个轻量的辅助指令,用来编译目标元素的内部HTML:
// 辅助指令代码 angular.module('yourApp').directive('compileInner', function($compile) { return { link: function(scope, element) { // 编译元素内部的所有内容 $compile(element.contents())(scope); } }; });
然后把这个指令加到custom-select-box上:
<custom-select-box id="month" model="month" model-required model-name="month" options="month.value as month.name for month in months" aria-label="{{month.name}}" compile-inner> <option value="">{{'dcl-spa.components.claim-and-link.month.mm'|translate}}</option> </custom-select-box>
这个辅助指令会在链接阶段帮AngularJS解析内部的插值和过滤器,注意如果custom-select-box用了隔离作用域,要确保辅助指令继承父作用域(默认scope: false就是继承父作用域,不用额外设置)。
方法3:尝试用ng-bind替代插值
有时候插值不生效是因为指令把内部HTML当作纯文本处理了,试试用ng-bind结合过滤器:
<custom-select-box id="month" model="month" model-required model-name="month" options="month.value as month.name for month in months" aria-label="{{month.name}}"> <option value="" ng-bind="('dcl-spa.components.claim-and-link.month.mm'|translate)"></option> </custom-select-box>
这个方法最简单,但能不能生效要看指令内部有没有保留ng-bind的处理逻辑,可以先试试这个方案。
内容的提问来源于stack exchange,提问作者vuvietkien
相关产品推荐
相关产品推荐

