在某些情况下,我发现自己在编写这样的标记代码:
<div ng-repeat="chapter in data.Chapters">
<table>
<tr ng-repeat="row in data.Rows">
<td ng-repeat="column in data.Columns">
{{chapter.Values[$parent.$index][$index].V}}
</td>
</tr>
</table>
</div>
最终的绑定表达式可能会变得复杂,如果您想象一个复杂对象的场景chapter.Values[$parent.$index][$index]
并且您必须访问它的所有属性,那么这些绑定会变得冗长且嘈杂。我写了一个简单的指令,允许我将我的标记更改为:
<div ng-repeat="chapter in data.Chapters">
<table>
<tr ng-repeat="row in data.Rows">
<td ng-repeat="column in data.Columns"
append-context name='item'
expression='chapter.Values[$parent.$index][$index]'>
{{item.V}}
</td>
</tr>
</table>
</div>
现在,在使用了我的指令(省略了代码,但它很简单)之后,我可以使用别名( )append-context
来引用我的对象,这大大简化了可读性。item
我对此有复杂的感觉,因为该指令在增强其布局能力方面并没有真正扩展 HTML,它真正做的是与范围管理有关。在其他情况下,我使用类似的方法来处理诸如重绘(setTimeout
通过特定指令透明地引入调用)之类的事情,同样与 HTML 呈现不严格相关。
您认为这是一种合法的方法,还是只是解决一个本来应该以不同方式解决的问题的技巧?
更新
这里提到的指令:
angular.module('directives', [])
.directive('appendContext', function () {
return {
restrict: 'A',
controller: function ($scope, $attrs) {
var expression = $attrs.expression,
name = $attrs.name;
$scope[name] = $scope.$eval(expression);
}
};
})
更新 2
@DavidChase 在他的评论中有一个很好的观点,尽管我对创建通用控制器仍然有复杂的感觉(但很可能只是我自己)。可能这个其他指令是一个更好的例子:
angular.module('directives', [])
.directive('progressive', ['$timeout', 'status', function (timer, status) {
return {
restrict: 'E',
transclude: true,
compile : function (el, attrs, transclude) {
return function (scope, element) {
status.working.start(function(working) {
timer(function () {
transclude(scope, function (node) {
element.append(node);
});
working.stop();
}, 10);
});
};
}
};
}])
在这种情况下,没有真正的 DOM 操作,因为我没有添加任何东西,但我使用了几个外部服务以“异步”方式嵌入内容,以便在长时间的情况下稍微改善 UI 体验刷新(避免卡住的 UI)。正如我所说,我不会向 DOM 添加任何内容,但我只是控制创建事物的时间。它是指令的好用例吗?