我有一个定义的指令:
$(function () {
angular.module(['myApp']).directive('rootSlider', function () {
return {
restrict: 'E',
template: '<ul><li ng-repeat="item in items"><img ng-src="{{item.url}}" /></li></ul>',
scope: {
items: '='
},
replace: true,
compile: function ($templateElement, $templateAttributes) {
return function ($scope, $element, $attrs) {
var $scope.items.length //expect 2, get 2
var numChildren $element.children().length //expect 2, get 0
};
}
};
});
});
虽然 $scope.items
属性有2个项目,并且在最终呈现的DOM中有两个 <li>
元素,但在链接函数 $element
中还没有子元素 .
在角度生命周期的什么时候我可以得到完全渲染的元素(我的意图是在这里使用jQuery滑块插件) .
标记是
<root-slider items="ModelPropertyWithTwoItems"></root-slider>
更新:
我能够通过$ watchCollection和$ evalAsync的组合使其正常工作 .
$(function () {
angular.module(['myApp']).directive('rootSlider', ['$timeout', function ($timeout) {
return {
restrict: 'E',
template: '<ul class="bxslider"><li ng-repeat="item in items"><img ng-src="{{item.url}}" /></li></ul>',
scope: {
items: '='
},
compile: function ($templateElement, $templateAttributes) {
return function ($scope, $element, $attrs) {
$scope.$watchCollection('items', function (newCollection, oldCollection) {
if ($scope.slider) {
$scope.$evalAsync(function () {
$scope.slider.reloadSlider();
});
}
else {
$scope.$evalAsync(function () {
$scope.slider = $element.find('.bxslider').bxSlider();
});
}
});
};
}
};
} ]);
});
监视集合在指令初始化时触发一次(因为它是一个集合,你无法比较newValue和oldValue,所以我最终将滑块对象添加到为指令实例创建的$ scope中 .
我使用$ evalAsync来推迟jQuery代码的执行(到目前为止)证明它可以避免在所有浏览器上闪烁(它似乎在$ timeout(function(){},0)之前运行 .
只需返回一个链接函数(而不是编译函数,结果是不必要的),可以简化上面的解决方案 .
2 回答
等待DOM在Angular中完成渲染的常用方法是使用
$timeout
. 这是各种选项的explanation和here's another look at this .所以这应该为你解决这个问题 . 在您的指令中包含
$timeout
:然后包装你的
在他关闭这个问题之前,有一个request for a more official feature supporting this和这里有's Angular'的评论:
到目前为止,似乎没有人对3emad最后发布的问题做出回应:
我认为这种方法令人鼓舞,没有人发布下行方面 .
您可能希望使用$watch来赶上模型的更改 .