我有一个附加到动态生成的指令 <table>
模板内的元素。该指令操纵该表内的DOM link
功能。问题是指令在表呈现之前运行(通过评估 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 */
}
};
});
从一般意义上讲,你不能仅仅通过对指令的指示来“完全确定” <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();
}
}
})
尝试包装 $timeout
链接函数中的代码,因为它将在呈现DOM后执行。
$timeout(function () {
//do your stuff here as the DOM has finished rendering already
});
别忘了注射 $timeout
在你的指令中:
.directive("directiveName", function($timeout) {
有很多选择,但我认为这个更清晰,因为$ timeout在渲染引擎完成其工作后执行。
一个干净的方法是使用类似的东西 lodash的 _.defer
方法。
你可以用它来打电话 _.defer(your_func, your_func_arg1, your_func_arg2, ...)
在你的链接里面执行方法,当前的调用堆栈已经清除并且一切准备就绪。
这样,您就不必估计了 $timeout
靠自己。