2

I've created a directive for Angular to know when a ng-repeat is finished. I've found the most common solution is something like is used here - Calling a function when ng-repeat has finished

But, Why the directive is just triggered when an element is added but not when is removed?

Here - ng-repeat list in Angular is not updated when a model element is spliced from the model array I've seen some suggestion about making a $scope.$apply, but is still not working because it says '$apply already in progress'

I've created here - a Plunker where you can reproduce it.

Thanks a lot!!!

Community
  • 1
  • 1
Mario Levrero
  • 3,345
  • 4
  • 26
  • 57

2 Answers2

4

The reason why the directive works when adding an item to the collection is that the link function is called when each repeated element is added to the dom. This works great when the collection is rendered for the first time and when an item is added to the end of the collection. It does not work when an item is added elsewhere in the collection e.g. at the beginning, as the link function is called for the new element but $last will be false.

When an item is removed from the collection no directive is created and hence no link function is called.

To get what you want you can create a watch on the collection and perform whatever you want to do in a $timeout so that it's done after the render:

$scope.$watchCollection('ta', function(){
    $timeout( function(){
        // the collection has rendered so do all my whizzy stuff
    });
});
Gruff Bunny
  • 27,738
  • 10
  • 72
  • 59
0

Most likely it is because ng-repeat doesn't iterate over the whole array when an item is spliced. It just removes that item from the array and removes the associated DOM node.

I don't know what exactly you are trying to achieve, but if you need to react to changes in the ng-repeat list, why don't you just $watch the array instead?

Harijs Deksnis
  • 1,366
  • 1
  • 13
  • 24
  • Thanks @Harijs, I'm using a directive instead of a $watch because the $watch is triggered before the render. I need to resize an element when the render of the ng-repeat elements has finished. – Mario Levrero Feb 20 '14 at 14:22
  • Well if you want to avoid the initial trigger you can set up your $watch function differently, e.g. the way ng docs actually show it (http://docs.angularjs.org/api/ng/type/$rootScope.Scope) `$scope.$watch('myvar', function (newValue, oldValue) { if ( newValue !== oldValue ) { //do your thing } });` – Harijs Deksnis Feb 20 '14 at 14:35
  • I don't mean about the initial trigger. I mean that, when I do an array.push(), first it fires the watch and then the new element is rendered (what makes all the sense). But I need to call my resize() function when all the elements of the ng-repeat has been rendered. – Mario Levrero Feb 20 '14 at 14:38