【发布时间】:2013-12-19 01:34:47
【问题描述】:
我定义了一个指令:
$(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中还没有子元素。
在 Angular 生命周期的哪个阶段,我可以得到完全渲染的元素(我的意图是在这里使用 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();
});
}
});
};
}
};
} ]);
});
Watch 集合在指令初始化时触发一次(因为它是一个集合,您无法比较 newValue 和 oldValue,因此我最终将滑块对象添加到为指令实例创建的 $scope 中。
我使用 $evalAsync 来推迟 jQuery 代码的执行,(到目前为止)证明可以避免在所有浏览器上闪烁(它似乎在 $timeout(function(){}, 0 之前运行)。
上面的解决方案可以通过只返回一个链接函数(而不是编译函数,结果证明是不必要的)来简化。
【问题讨论】:
标签: jquery angularjs angularjs-directive