diff --git a/src/directives.js b/src/directives.js index aa30fab209cc..00e6a1d78983 100644 --- a/src/directives.js +++ b/src/directives.js @@ -568,18 +568,25 @@ angularDirective("ng:submit", function(expression, element) { }); }); - function ngClass(selector) { return function(expression, element){ - var existing = element[0].className + ' '; return function(element){ - this.$onEval(function(){ - if (selector(this.$index)) { - var value = this.$eval(expression); - if (isArray(value)) value = value.join(' '); - element[0].className = trim(existing + value); - } - }, element); + if(selector(this.$index)) { + this.$watch(expression, function(newCls, oldCls) { + var cls = element.attr('class'); + if (isArray(newCls)) newCls = newCls.join(' '); + if (isArray(oldCls)) oldCls = oldCls.join(' '); + + // The time when newCls == oldCLs is when $watch just started + if (newCls == oldCls) { + cls += ' ' + newCls; + } else { + cls = cls.replace(' ' + oldCls, ' ' + newCls); + } + + element.attr('class', cls); + }); + } }; }; } diff --git a/test/directivesSpec.js b/test/directivesSpec.js index 713147adea30..a640fc503a96 100644 --- a/test/directivesSpec.js +++ b/test/directivesSpec.js @@ -177,7 +177,7 @@ describe("directive", function(){ describe('ng:class', function() { - it('should add new and remove old classes dynamically', function() { + it('should change current class or remove old classes dynamically', function() { var scope = compile('
'); scope.dynClass = 'A'; scope.$eval(); @@ -204,6 +204,45 @@ describe("directive", function(){ expect(element.hasClass('A')).toBeTruthy(); expect(element.hasClass('B')).toBeTruthy(); }); + + it('should preserve class added post compilation', function() { + var scope = compile(''); + scope.dynClass = 'A'; + scope.$eval(); + expect(element.hasClass('existing')).toBe(true); + + // add extra class, change model and eval + element.addClass('newClass'); + scope.dynClass = 'B'; + scope.$eval(); + + expect(element.hasClass('existing')).toBe(true); + expect(element.hasClass('B')).toBe(true); + expect(element.hasClass('newClass')).toBe(true); + }); + + it('should preserve class added post compilation even without existing classes"', function() { + var scope = compile(''); + scope.dynClass = 'A'; + scope.$eval(); + expect(element.hasClass('A')).toBe(true); + + // add extra class, change model and eval + element.addClass('newClass'); + scope.dynClass = 'B'; + scope.$eval(); + + expect(element.hasClass('B')).toBe(true); + expect(element.hasClass('newClass')).toBe(true); + }); + + it('should preserve right classes"', function() { + var scope = compile(''); + scope.dynCls = 'panel'; + scope.dynCls = 'foo'; + scope.$eval(); + expect(element.attr('class')).toBe('ui-panel ui-selected ng-directive foo'); + }); });