Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use AngularJS directive to change classes of ng-repeat elements

I am trying to conditionally change the class of an element that is nested in an unordered list.

When not using ng-repeat to create the list, I can use the jqlite selector .children() to find the correct element and change the class.

However I am using ng-repeat to create the list and I can't figure out how to access the specific list element that I want. .children() always returns undefined.

here is a jsfiddle of what I am trying to do http://jsfiddle.net/whitehead1415/ENtTC/3/

app.directive('myDirective1', function () {
    return {
        restrict: 'A',
        link: function ($scope, element, attrs, controller) {
            //for some reason element.children()[0] is undefined
            //why? what can I do about it?
            angular.element(element.children()[0]).css('background', 'grey')
        }
    };
});

I need to be able to change the class based on 2 things

  1. when the user clicks on the specific element the element needs to highlight
  2. when the user clicks on a button that is the next element will be highlighted (that button isn't included in the jsfiddle)

I thought about putting the directive on each list element, but the only problem is that I don't know how to make them all aware of each other so only one element is highlighted at a time

like image 229
whitehead1415 Avatar asked May 25 '13 16:05

whitehead1415


1 Answers

The reason this happens is because ng-repeat alters the template DOM in such a way that the children do not exist at the time the directive compiles. You need to set a $watch on element.children() in the directive so that the directive will be notified when the children are added and apply the CSS at that time. Do this in your link function (which is a postLink function when declared as a directive method):

$scope.$watch(element.children(),function(){
    var children = element.children();
    for(var i=0;i<children.length;i++){
        if(children[i].nodeType !== 8){
            angular.element(children[i]).css('background', 'grey');
        }
    }
});

The $watch also needs to check and make sure that the nodeType is not a comment (type 8) because ng-repeat inserts comments, which will throw an error if you try to apply CSS.

Fiddle: Here is the working fiddle

like image 163
Dan Avatar answered Sep 27 '22 00:09

Dan