Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS watch DOM change

I have one auto-carousel directive which iterates through the linked element's children.

The children however are not yet loaded in the DOM, because their ng-ifs expressions have not been parsed yet.

How can I make sure the parent directive knows there have been changes to it's DOM tree?

        <ul class="unstyled" auto-carousel>           <li class="slide" ng-if="name">{{name}}</li>           ...           <li class="slide" ng-if="email">{{email}}</li>         </ul> 

I could use $timeout but that feels unreliable. I could also use ng-show instead of ng-if but that does not answer the question and not what I need.

like image 845
pilau Avatar asked Jan 24 '14 12:01

pilau


1 Answers

So here's what I ended up doing:

I discovered you could pass a function to $scope.$watch. From there, it's pretty straightforward to return the value of the expression you want to watch for changes. It will work exactly like passing a key string for a property on the scope.

link: function ($scope, $el, $attrs) {   $scope.$watch(     function () { return $el[0].childNodes.length; },     function (newValue, oldValue) {       if (newValue !== oldValue) {         // code goes here       }     }   ); } 

I am watching childNodes, not children, because the childNodes list holds elements as well as text nodes and comments. This is priceless because Angular uses comment placeholders for directives like ng-repeat, ng-if, ng-switch and ng-include which perform transclusion and alter the DOM, while children only holds elements.

like image 145
pilau Avatar answered Sep 23 '22 17:09

pilau