diff --git a/src/ng/directive/ngClass.js b/src/ng/directive/ngClass.js index e054d4c6d7a4..6ba73e60c8ae 100644 --- a/src/ng/directive/ngClass.js +++ b/src/ng/directive/ngClass.js @@ -3,17 +3,25 @@ function classDirective(name, selector) { name = 'ngClass' + name; return ngDirective(function(scope, element, attr) { - scope.$watch(attr[name], function(newVal, oldVal) { + // Reusable function for re-applying the ngClass + function reapply(newVal, oldVal) { if (selector === true || scope.$index % 2 === selector) { if (oldVal && (newVal !== oldVal)) { - if (isObject(oldVal) && !isArray(oldVal)) - oldVal = map(oldVal, function(v, k) { if (v) return k }); - element.removeClass(isArray(oldVal) ? oldVal.join(' ') : oldVal); - } - if (isObject(newVal) && !isArray(newVal)) - newVal = map(newVal, function(v, k) { if (v) return k }); - if (newVal) element.addClass(isArray(newVal) ? newVal.join(' ') : newVal); } - }, true); + if (isObject(oldVal) && !isArray(oldVal)) + oldVal = map(oldVal, function(v, k) { if (v) return k }); + element.removeClass(isArray(oldVal) ? oldVal.join(' ') : oldVal); + } + if (isObject(newVal) && !isArray(newVal)) + newVal = map(newVal, function(v, k) { if (v) return k }); + if (newVal) element.addClass(isArray(newVal) ? newVal.join(' ') : newVal); + } + }; + scope.$watch(attr[name], reapply, true); + + attr.$observe('class', function(value) { + var ngClass = scope.$eval(attr[name]); + reapply(ngClass, ngClass); + }); }); } diff --git a/test/ng/directive/ngClassSpec.js b/test/ng/directive/ngClassSpec.js index e8685b7dc0bb..fc46bf7c03de 100644 --- a/test/ng/directive/ngClassSpec.js +++ b/test/ng/directive/ngClassSpec.js @@ -201,4 +201,37 @@ describe('ngClass', function() { expect(e2.hasClass('C')).toBeFalsy(); expect(e2.hasClass('D')).toBeFalsy(); })); + + + it('should reapply ngClass when interpolated class attribute changes', inject(function($rootScope, $compile) { + element = $compile('
')($rootScope); + + $rootScope.$apply(function() { + $rootScope.cls = "two"; + $rootScope.four = true; + }); + expect(element).toHaveClass('one'); + expect(element).toHaveClass('two'); // interpolated + expect(element).toHaveClass('three'); + expect(element).toHaveClass('four'); + + $rootScope.$apply(function() { + $rootScope.cls = "too"; + }); + expect(element).toHaveClass('one'); + expect(element).toHaveClass('too'); // interpolated + expect(element).toHaveClass('three'); + expect(element).toHaveClass('four'); // should still be there + expect(element.hasClass('two')).toBeFalsy(); + + $rootScope.$apply(function() { + $rootScope.cls = "to"; + }); + expect(element).toHaveClass('one'); + expect(element).toHaveClass('to'); // interpolated + expect(element).toHaveClass('three'); + expect(element).toHaveClass('four'); // should still be there + expect(element.hasClass('two')).toBeFalsy(); + expect(element.hasClass('too')).toBeFalsy(); + })); });