我有一个定义的指令:
$(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。 / p>
我使用$ evalAsync来推迟jQuery代码的执行(到目前为止)证明可以避免在所有浏览器上闪烁(它似乎在$ timeout(function(){},0)之前运行。
上面的解决方案可能只需返回一个链接函数(而不是编译函数,结果是不必要的)就可以简化。
答案 0 :(得分:2)
等待DOM在Angular中完成渲染的常用方法是使用$timeout
。以下是各种选项的explanation和here's another look at this。
所以这应该为你解决这个问题。在您的指令中包含$timeout
:
angular.module(['myApp']).directive('rootSlider', function ($timeout) {
然后换行
$timeout(function() {
var numChildren $element.children().length;
},0);
在关闭此问题之前,已经有request for a more official feature supporting this和Angular自己Misko Hevery的评论:
这是一个非常复杂的问题。问题在于 数据绑定没有明确的更新周期的开始/结束,它是 继续。我相信这不是你要找的答案,但是 角度与其他框架不同,所以它的生活方式与众不同 规则。
你怎么能想到这会起作用?什么样的,何时应该 你会收到这些通知。
到目前为止,似乎没有人对3emad最后贴出的问题做出回应:
我只是对$ timeout下方感到好奇
我认为这种做法令人鼓舞,没有人发布下行。
答案 1 :(得分:1)
您可能希望使用$watch
来赶上模型的更改。
$scope.$watch('items', function(newValue) {
// logic about items here...
}, true); // pass true since it should be an array