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>
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") })
}
}
})
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.
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:
JavaScript:
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.
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.Then I broadcast a custom event (
event:repeat-done
), and pass the last rendered repeat element as a parameter to the parent scope.I could then pick up this event in my auto-complete directive and initialize my Chosen plugin over the fully-rendered select element!
This technique could then be generically applied to any time you need to detect when an ng-repeat directive is done. For your example:
EDIT: 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.A simple way to do it is to create a new directive called 'repeat-done' and use it where the 'ng-repeat' is. Then you can notify the 'myscroll' directive (parent scope) whatever you need.