我有一个指令附加到模板中动态生成的<table>
元素。该指令在link
函数内操作该表的DOM。问题是指令在表呈现之前运行(通过评估ng-repeat
指令) - 表是空的。
问题
如何确保在完全呈现表后运行该指令?
<table directive-name>
<tr ng-repeat="...">
<td ng-repeat="..."></td>
</tr>
</table>
module.directive("directiveName", function() {
return {
scope: "A",
link: function(scope, element, attributes) {
/* I need to be sure that the table is already fully
rendered when this code runs */
}
};
});
答案 0 :(得分:6)
从一般意义上说,你不能完全确定&#34;只需在<table>
元素上有一个指令。
但在某些情况下你可以肯定。在您的情况下,如果内部内容为ng-repeat
- ed,那么如果ngRepeat
工作的项目数组已准备就绪,那么实际DOM元素将在摘要周期结束时准备就绪。您可以在$timeout
之后以0延迟捕获它:
link: function(scope, element){
$timeout(function(){
console.log(element.find("tr").length); // will be > 0
})
}
但是,从一般意义上讲,您无法确定捕获内容。如果ngRepeat
ed数组还没有呢?或者如果有ng-include
而该怎么办?
<table directive-name ng-include="'templates/tr.html'">
</table>
或者,如果有一个与ngRepeat
不同的自定义指令呢?
但是如果您完全控制了内容,一种可能的方法就是将一些辅助指令作为最内层/最后一个元素包含在内,并在它链接时让它与其父directiveName
联系:
<table directive-name>
<tr ng-repeat="...">
<td ng-repeat="...">
<directive-name-helper ng-if="$last">
</td>
</tr>
</table>
.directive("directiveNameHelper", function(){
return {
require: "?^directiveName",
link: function(scope, element, attrs, ctrl){
if (!ctrl) return;
ctrl.notifyDone();
}
}
})
答案 1 :(得分:5)
尝试在链接函数的$timeout
中包装,因为它将在呈现DOM后执行。
$timeout(function () {
//do your stuff here as the DOM has finished rendering already
});
不要忘记在你的指令中注入$timeout
:
.directive("directiveName", function($timeout) {
有很多替代方案,但我认为这个更清晰,因为$ timeout在渲染引擎完成其工作后执行。
答案 2 :(得分:0)
干净的方法是使用像lodash's _.defer
method这样的东西。
当当前调用堆栈已清除且一切准备就绪时,您可以在链接中使用_.defer(your_func, your_func_arg1, your_func_arg2, ...)
调用它来执行该方法。
这样,您就不必自己估算$timeout
。