From fbf2987483b8e5fe7317bca358480035b3489983 Mon Sep 17 00:00:00 2001 From: Joey Perrott Date: Mon, 20 Nov 2017 09:28:15 -0800 Subject: [PATCH] fix(tabs): detach tab portal when tab hides from view (#8486) --- src/lib/tabs/tab-body.ts | 23 ++++++++++++++--------- src/lib/tabs/tab-group.spec.ts | 13 +++++++++++++ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/lib/tabs/tab-body.ts b/src/lib/tabs/tab-body.ts index e08eb716b14f..9b5e906e55a0 100644 --- a/src/lib/tabs/tab-body.ts +++ b/src/lib/tabs/tab-body.ts @@ -81,15 +81,19 @@ export class MatTabBodyPortal extends _MatTabBodyPortalBaseClass implements OnIn ngOnInit(): void { if (this._host._isCenterPosition(this._host._position)) { this.attach(this._host._content); - } else { - this._centeringSub = this._host._beforeCentering.subscribe(() => { - this.attach(this._host._content); - this._centeringSub.unsubscribe(); - }); } + this._centeringSub = this._host._beforeCentering.subscribe((isCentering: boolean) => { + if (isCentering) { + if (!this.hasAttached()) { + this.attach(this._host._content); + } + } else { + this.detach(); + } + }); } - /** Clean up subscription if necessary. */ + /** Clean up centering subscription. */ ngOnDestroy(): void { if (this._centeringSub && !this._centeringSub.closed) { this._centeringSub.unsubscribe(); @@ -136,7 +140,7 @@ export class MatTabBody implements OnInit { @Output() _onCentering: EventEmitter = new EventEmitter(); /** Event emitted before the centering of the tab begins. */ - @Output() _beforeCentering: EventEmitter = new EventEmitter(); + @Output() _beforeCentering: EventEmitter = new EventEmitter(); /** Event emitted when the tab completes its animation towards the center. */ @Output() _onCentered: EventEmitter = new EventEmitter(true); @@ -185,8 +189,9 @@ export class MatTabBody implements OnInit { } _onTranslateTabStarted(e: AnimationEvent): void { - if (this._isCenterPosition(e.toState)) { - this._beforeCentering.emit(); + const isCentering = this._isCenterPosition(e.toState); + this._beforeCentering.emit(isCentering); + if (isCentering) { this._onCentering.emit(this._elementRef.nativeElement.clientHeight); } } diff --git a/src/lib/tabs/tab-group.spec.ts b/src/lib/tabs/tab-group.spec.ts index 03780b818d27..16aa2266ef04 100644 --- a/src/lib/tabs/tab-group.spec.ts +++ b/src/lib/tabs/tab-group.spec.ts @@ -350,6 +350,19 @@ describe('MatTabGroup', () => { expect(fixture.componentInstance.legumes).toBeTruthy(); }); + it('should only have the active tab in the DOM', async(() => { + expect(fixture.nativeElement.textContent).toContain('Pizza, fries'); + expect(fixture.nativeElement.textContent).not.toContain('Peanuts'); + + tabGroup.selectedIndex = 3; + fixture.detectChanges(); + // Use whenStable to wait for async observables and change detection to run in content. + fixture.whenStable().then(() => { + expect(fixture.nativeElement.textContent).not.toContain('Pizza, fries'); + expect(fixture.nativeElement.textContent).toContain('Peanuts'); + }); + })); + it('should support setting the header position', () => { let tabGroupNode = fixture.debugElement.query(By.css('mat-tab-group')).nativeElement;