fix(ngClass): do not deconstruct classes on element removal (#10303)
Prior to this fix [ngClass] would remove all dynamic classes when destroyed. It's essential that classes are persisted such that remove-based animations will still be stylistically correct. This patch fixes this issue. Closes #10008 Closes #10303
This commit is contained in:
parent
62e7c0f464
commit
ba88db5141
|
@ -6,7 +6,7 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {CollectionChangeRecord, Directive, DoCheck, ElementRef, Input, IterableDiffer, IterableDiffers, KeyValueChangeRecord, KeyValueDiffer, KeyValueDiffers, OnDestroy, Renderer} from '@angular/core';
|
||||
import {CollectionChangeRecord, Directive, DoCheck, ElementRef, Input, IterableDiffer, IterableDiffers, KeyValueChangeRecord, KeyValueDiffer, KeyValueDiffers, Renderer} from '@angular/core';
|
||||
|
||||
import {StringMapWrapper, isListLikeIterable} from '../facade/collection';
|
||||
import {isArray, isPresent, isString} from '../facade/lang';
|
||||
|
@ -75,7 +75,7 @@ import {isArray, isPresent, isString} from '../facade/lang';
|
|||
* @stable
|
||||
*/
|
||||
@Directive({selector: '[ngClass]'})
|
||||
export class NgClass implements DoCheck, OnDestroy {
|
||||
export class NgClass implements DoCheck {
|
||||
private _iterableDiffer: IterableDiffer;
|
||||
private _keyValueDiffer: KeyValueDiffer;
|
||||
private _initialClasses: string[] = [];
|
||||
|
@ -129,8 +129,6 @@ export class NgClass implements DoCheck, OnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void { this._cleanupClasses(this._rawClass); }
|
||||
|
||||
private _cleanupClasses(rawClassVal: string[]|Set<string>|{[key: string]: any}): void {
|
||||
this._applyClasses(rawClassVal, true);
|
||||
this._applyInitialClasses(false);
|
||||
|
|
|
@ -874,6 +874,39 @@ function declareTests({useJit}: {useJit: boolean}) {
|
|||
})));
|
||||
});
|
||||
|
||||
describe('ng directives', () => {
|
||||
describe('[ngClass]', () => {
|
||||
it('should persist ngClass class values when a remove element animation is active',
|
||||
inject(
|
||||
[TestComponentBuilder, AnimationDriver],
|
||||
fakeAsync(
|
||||
(tcb: TestComponentBuilder, driver: InnerContentTrackingAnimationDriver) => {
|
||||
makeAnimationCmp(
|
||||
tcb, `<div [ngClass]="exp2" *ngIf="exp" @trigger></div>`,
|
||||
[
|
||||
trigger('trigger', [transition('* => void', [animate(1000)])]),
|
||||
],
|
||||
(fixture: any /** TODO #9100 */) => {
|
||||
var cmp = fixture.debugElement.componentInstance;
|
||||
cmp.exp = true;
|
||||
cmp.exp2 = 'blue';
|
||||
fixture.detectChanges();
|
||||
flushMicrotasks();
|
||||
|
||||
expect(driver.log.length).toEqual(0);
|
||||
|
||||
cmp.exp = false;
|
||||
fixture.detectChanges();
|
||||
flushMicrotasks();
|
||||
|
||||
var animation = driver.log.pop();
|
||||
var element = animation['element'];
|
||||
(<any>expect(element)).toHaveCssClass('blue');
|
||||
});
|
||||
})));
|
||||
});
|
||||
});
|
||||
|
||||
describe('animation states', () => {
|
||||
it('should throw an error when an animation is referenced that isn\'t defined within the component annotation',
|
||||
inject(
|
||||
|
|
|
@ -291,14 +291,13 @@ export declare const NG_VALIDATORS: OpaqueToken;
|
|||
export declare const NG_VALUE_ACCESSOR: OpaqueToken;
|
||||
|
||||
/** @stable */
|
||||
export declare class NgClass implements DoCheck, OnDestroy {
|
||||
export declare class NgClass implements DoCheck {
|
||||
initialClasses: string;
|
||||
ngClass: string | string[] | Set<string> | {
|
||||
[key: string]: any;
|
||||
};
|
||||
constructor(_iterableDiffers: IterableDiffers, _keyValueDiffers: KeyValueDiffers, _ngEl: ElementRef, _renderer: Renderer);
|
||||
ngDoCheck(): void;
|
||||
ngOnDestroy(): void;
|
||||
}
|
||||
|
||||
/** @experimental */
|
||||
|
|
Loading…
Reference in New Issue