From 1438922ffb53884292da5b986c47b0396ee116ba Mon Sep 17 00:00:00 2001 From: Tobias Bosch Date: Thu, 23 Jul 2015 16:22:14 -0700 Subject: [PATCH] fix(class): correctly clean up on destroy Fixes #3249 Closes #3256 --- modules/angular2/src/directives/class.ts | 9 ++++-- .../angular2/test/directives/class_spec.ts | 28 +++++++++++++++++-- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/modules/angular2/src/directives/class.ts b/modules/angular2/src/directives/class.ts index f55ec06ec4..188c4e1ed7 100644 --- a/modules/angular2/src/directives/class.ts +++ b/modules/angular2/src/directives/class.ts @@ -28,8 +28,11 @@ import {ListWrapper, StringMapWrapper, isListLikeIterable} from 'angular2/src/fa * * ``` */ -@Directive( - {selector: '[class]', lifecycle: [LifecycleEvent.onCheck], properties: ['rawClass: class']}) +@Directive({ + selector: '[class]', + lifecycle: [LifecycleEvent.onCheck, LifecycleEvent.onDestroy], + properties: ['rawClass: class'] +}) export class CSSClass { _pipe: Pipe; _rawClass; @@ -58,6 +61,8 @@ export class CSSClass { } } + onDestroy(): void { this._cleanupClasses(this._rawClass); } + private _cleanupClasses(rawClassVal): void { if (isPresent(rawClassVal)) { if (isListLikeIterable(rawClassVal)) { diff --git a/modules/angular2/test/directives/class_spec.ts b/modules/angular2/test/directives/class_spec.ts index f616d034fc..7845231b48 100644 --- a/modules/angular2/test/directives/class_spec.ts +++ b/modules/angular2/test/directives/class_spec.ts @@ -14,13 +14,36 @@ import { xit, } from 'angular2/test_lib'; import {List, ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection'; -import {Component, View} from 'angular2/angular2'; +import {Component, View, NgFor, bind} from 'angular2/angular2'; import {DOM} from 'angular2/src/dom/dom_adapter'; import {CSSClass} from 'angular2/src/directives/class'; +import {APP_VIEW_POOL_CAPACITY} from 'angular2/src/core/compiler/view_pool'; export function main() { describe('binding to CSS class list', () => { + describe('viewpool support', () => { + beforeEachBindings(() => { return [bind(APP_VIEW_POOL_CAPACITY).toValue(100)]; }); + + it('should clean up when the directive is destroyed', + inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { + var template = '
'; + tcb.overrideTemplate(TestComponent, template) + .createAsync(TestComponent) + .then((rootTC) => { + rootTC.componentInstance.items = [['0']]; + rootTC.detectChanges(); + rootTC.componentInstance.items = [['1']]; + rootTC.detectChanges(); + expect(rootTC.componentViewChildren[1].nativeElement.className) + .toEqual('ng-binding 1'); + + async.done(); + }); + })); + }); + + describe('expressions evaluating to objects', () => { it('should add classes specified in an object literal', @@ -344,9 +367,10 @@ export function main() { } @Component({selector: 'test-cmp'}) -@View({directives: [CSSClass]}) +@View({directives: [CSSClass, NgFor]}) class TestComponent { condition: boolean = true; + items: any[]; arrExpr: List = ['foo']; objExpr = {'foo': true, 'bar': false}; strExpr = 'foo';