Search code examples
angularjsangular-directive

Angular class change directive doesn't work


I want to add a directive that will do something when an element class is changed.

My directive is:

(function (angular) {

angular.module('myApp')
    .directive('myClassWatch', myClassWatch);

function myClassWatch() {
    return {
        restrict: 'A',
        link: function (scope, element, attrs, controller) {
            scope.$watch(function () {
                return element.attr('class');
            }, function (newValue, oldValue) {
                debugger;
                if(oldValue !== newValue)
                    console.log('class changed from ' + oldValue + ' to ' + newValue);
            });
        }
    }
}
})(angular);

The html is:

<div class="top-icons-item popup-container popup-link-container" my-class-watch>

</div>

I do some actions elsewhere that toggles the class "open" in my div element - it is visible in the html - yet the debugger is never called (also no console logs of course). I can see that the link function is called on page load and the debugger also stops, but thats only on page load and not afterwards when I actually do actions that adds another class.

I have read several issued here before including Directive : $observe, class attribute change caught only once but I can't understand why I don't get the same result. What can I do to try check why this occures?

Update: The class change is made using jQuery not in a controller but in an old jquery watches code. May this be cause? could angular be unaware of class change when its not done from an angular code?


Solution

  • Wrap your jQuery code into $apply.

    It similar to you are making changes to $scope out of angular context(jquery ajax, setTimeout, etc). Use $apply to make angular know about the changes done.

        angular.element(document.getElementById('app')).injector().invoke(['$compile', '$rootScope', function($compile, $rootScope) {
           $rootScope.$apply(function() {
               //your jquery code goes here...
               var a = document.getElementById('abc');
               angular.element(a).addClass('hello');
           });
        }]);