我有一个auto-carousel
指令,它遍历链接元素的子。
但是孩子们还没有加载到DOM中,因为他们的ng-if
表达式还没有被解析过。
如何确保父指令知道它的DOM树有变化?
<ul class="unstyled" auto-carousel>
<li class="slide" ng-if="name">{{name}}</li>
...
<li class="slide" ng-if="email">{{email}}</li>
</ul>
我可以使用$timeout
但感觉不可靠。我也可以使用ng-show
代替ng-if
,但这不会回答问题而不是我需要的问题。
答案 0 :(得分:74)
所以这就是我最终做的事情:
我发现你可以将一个函数传递给$scope.$watch
。从那里,返回要监视更改的表达式的值非常简单。它的工作方式与在范围内传递属性的键字符串完全相同。
link: function ($scope, $el, $attrs) {
$scope.$watch(
function () { return $el[0].childNodes.length; },
function (newValue, oldValue) {
if (newValue !== oldValue) {
// code goes here
}
}
);
}
我正在关注childNodes
,而不是children
,因为childNodes
列表包含元素以及文本节点和注释。这是无价的,因为Angular对ng-repeat
,ng-if
,ng-switch
和ng-include
等指令使用注释占位符来执行转换并更改DOM,而children
仅保留元件。
答案 1 :(得分:18)
如果您需要观察元素主题中更深层次的变化,MutationObserver就是您的选择:
.directive('myDirective', function() {
return {
...
link: function(scope, element, attrs) {
var observer = new MutationObserver(function(mutations) {
// your code here ...
});
observer.observe(element[0], {
childList: true,
subtree: true
});
}
};
});
答案 2 :(得分:5)
在你的情况下,你可以
<ul class="unstyled" auto-carousel>
<li class="slide" ng-if="name" dom-on-create="nameCreated()">{{name}}</li>
<li class="slide" ng-if="email" dom-on-destroy="emailDestroyed()">{{email}}</li>
</ul>
目前仅支持dom-on-create
和dom-on-destroy
,但其性能优于接受的答案,因为它只会针对每个dom事件触发一次,而不是反复检查$ watch回调。
答案 3 :(得分:1)
虽然我认为没有使用angular的推荐,但你可以使用ng-init,它会在元素初始化时触发:
<ul class="unstyled" auto-carousel>
<li class="slide" ng-if="name" ng-init="recheck()">{{name}}</li>
<li class="slide" ng-if="email" ng-init="recheck()">{{email}}</li>
</ul>
答案 4 :(得分:0)
您可以尝试首先在链接函数中编译指令内容。例如:
angular.module('myApp').directive('autoCarousel', ['$compile', function ($compile) {
return {
templateUrl: 'views/auto-carousel.html',
restrict: 'A',
replace: true,
link: function (scope, element, attr) {
$compile(element.contents())(scope);
// your code goes here
}
}
}]);