以防其他人偶然发现这个问题,我想分享我的解决方案。dluz 的回答为我指明了正确的方向,但我采取了更“优雅”的方法。
为了给您提供上下文,我需要将此系统与 ng-repeat 一起使用来填充选择下拉列表中的选项。ng-options 与jQuery Chosen插件不兼容(顺便说一句,漂亮的自动完成/搜索下拉插件!),一旦所有选项完成渲染,我需要初始化插件。
HTML:
<select auto-complete ng-model="stuff">
<option ng-repeat="item in items" value="{{ item.value }}">{{ item.name }}</option>
</select>
JavaScript:
// Extension of built-in ngRepeat directive - broadcasts to its parent when it is finished.
// Passes the last element rendered as an event parameter.
app.directive('ngRepeat', function () {
return {
restrict: 'A',
link: function ($scope, $elem, $attrs) {
if ($scope.$last)
$scope.$parent.$broadcast('event:repeat-done', $elem);
}
};
});
// My directive for working with the Chosen plugin.
app.directive('autoComplete', function () {
return {
restrict: 'A',
link: function ($scope, $elem, $attrs) {
$scope.$on('event:repeat-done', function () {
setTimeout(function () {
if (!$elem.children(':first-child').is('[disabled]'))
$elem.prepend('<option disabled="disabled"></option>');
$elem.chosen({ disable_search_threshold: 10, width: '100%' });
$elem.trigger('chosen:updated');
});
});
}
};
});
如您所见,我只是用我的广播器函数扩展了内置的 ng-repeat 指令。由于它是一种非侵入性添加,因此我毫不犹豫地将其应用到 ng-repeat 的所有用途中。
$elem.parent().scope()
在函数本身中,我使用 Angular$scope.$parent
来获取父上下文,而不是查看(这可能——而且在大多数情况下会——工作)。
然后我广播一个自定义事件 ( event:repeat-done
),并将最后呈现的重复元素作为参数传递给父作用域。
然后我可以在我的自动完成指令中选择这个事件,并在完全渲染的选择元素上初始化我的选择插件!
然后,该技术可以普遍应用于您需要检测何时完成 ng-repeat 指令的任何时间。对于您的示例:
myapp.directive("myscroll", function () {
return{
restrict: "E",
transclude: true,
template: "<span class='left'></span><div class='mask' ng-transclude></div><span class='right'></span>",
link: function (scope, element, attr) {
scope.$on("event:repeat-done",function(){ console.log("ng-repeat rendered") })
}
}
})
编辑:在某些情况下,在 rootScope 中一直检测这些事件可能是有益的。如果是这种情况,您可以替换$scope.$parent.$broadcast
为$scope.$emit
让事件冒泡而不是向下冒泡。