问题描述
在下面的代码中,angular 指令myscroll"如何知道正在创建什么 ng-repeat 元素?
In the code below, how does the angular directive 'myscroll' know what ng-repeat elements are being created?
<myscroll>
<div ng-repeat="a in arr">{{a}}</div>
</myscroll>
我知道 $last 事件没有被触发到父指令,我该如何解决这个问题?
I know that the $last event is not fired to the parent directive, how can I solve this?
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.$watch("$last",function(){ console.log("ng-repeat rendered") })
}
}
})
推荐答案
为了防止其他人偶然发现这个问题,我想分享我的解决方案.dluz 的回答为我指明了正确的方向,但我采取了更优雅"的方法.
Just in case someone else stumbles upon this question, I wanted to share my solution. dluz's answer pointed me in the right direction, but I took a more 'elegant' approach.
为了给你提供上下文,我需要使用这个系统和 ng-repeat 来填充选择下拉列表中的选项.ng-options 与 jQuery Chosen 插件(漂亮的自动完成/搜索下拉插件,由方式!),我需要在所有选项都完成渲染后初始化插件.
To give you context, I needed to use this system with ng-repeat to populate the options in a select dropdown. There was an incompatibility with ng-options with the jQuery Chosen plugin (beautiful autocomplete/search dropdown plugin, by the way!), and I needed to initialize the plugin once all the options were finished rendering.
HTML:
<select auto-complete ng-model="stuff">
<option ng-repeat="item in items" value="{{ item.value }}">{{ item.name }}</option>
</select>
JavaScript:
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 的所有用途中.
As you can see, I simply extended the built-in ng-repeat directive with my broadcaster function. Since it's a non-invasive addition, I have no qualms with implementing this into all uses of ng-repeat.
在函数本身中,我使用 Angular 的 $scope,而不是查看
获取父上下文.$elem.parent().scope()
(这可以 - 而且在大多数情况下可以 - 工作).$parent
Within the function itself, instead of looking at $elem.parent().scope()
(which could - and in most situations would - work), I use Angular's $scope.$parent
to fetch the parent context.
然后我广播一个自定义事件(event:repeat-done
),并将最后呈现的重复元素作为参数传递给父作用域.
Then I broadcast a custom event (event:repeat-done
), and pass the last rendered repeat element as a parameter to the parent scope.
然后我可以在我的自动完成指令中选择这个事件并在完全渲染的 select 元素上初始化我的 Chosen 插件!
I could then pick up this event in my auto-complete directive and initialize my Chosen plugin over the fully-rendered select element!
这种技术可以普遍应用于您需要检测何时完成 ng-repeat 指令的任何时间.例如:
This technique could then be generically applied to any time you need to detect when an ng-repeat directive is done. For your example:
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
以使事件向上冒泡而不是向下冒泡.
For some cases it may be beneficial to detect these events all the way up at the rootScope. If this is the case, you could replace $scope.$parent.$broadcast
with $scope.$emit
to have the event bubble up instead of down.
这篇关于在角度指令中完成 ng-repeat的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!