+
diff --git a/src/lib/tabs/tab-nav-bar/tab-nav-bar.spec.ts b/src/lib/tabs/tab-nav-bar/tab-nav-bar.spec.ts
index 400fb4f91f9..275d2b6df66 100644
--- a/src/lib/tabs/tab-nav-bar/tab-nav-bar.spec.ts
+++ b/src/lib/tabs/tab-nav-bar/tab-nav-bar.spec.ts
@@ -1,12 +1,12 @@
-import {async, ComponentFixture, TestBed, fakeAsync, tick} from '@angular/core/testing';
+import {async, ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing';
import {MdTabsModule} from '../index';
import {MdTabNavBar} from './tab-nav-bar';
import {Component, ViewChild} from '@angular/core';
import {By} from '@angular/platform-browser';
import {ViewportRuler} from '../../core/overlay/position/viewport-ruler';
import {FakeViewportRuler} from '../../core/overlay/position/fake-viewport-ruler';
-import {dispatchMouseEvent, dispatchFakeEvent} from '../../core/testing/dispatch-events';
-import {LayoutDirection, Dir} from '../../core/rtl/dir';
+import {dispatchFakeEvent, dispatchMouseEvent} from '../../core/testing/dispatch-events';
+import {Dir, LayoutDirection} from '../../core/rtl/dir';
import {Subject} from 'rxjs/Subject';
@@ -37,20 +37,19 @@ describe('MdTabNavBar', () => {
beforeEach(() => {
fixture = TestBed.createComponent(SimpleTabNavBarTestApp);
+ fixture.detectChanges();
});
it('should change active index on click', () => {
- let component = fixture.debugElement.componentInstance;
-
// select the second link
let tabLink = fixture.debugElement.queryAll(By.css('a'))[1];
tabLink.nativeElement.click();
- expect(component.activeIndex).toBe(1);
+ expect(fixture.componentInstance.activeIndex).toBe(1);
// select the third link
tabLink = fixture.debugElement.queryAll(By.css('a'))[2];
tabLink.nativeElement.click();
- expect(component.activeIndex).toBe(2);
+ expect(fixture.componentInstance.activeIndex).toBe(2);
});
it('should re-align the ink bar when the direction changes', () => {
@@ -64,6 +63,31 @@ describe('MdTabNavBar', () => {
expect(inkBar.alignToElement).toHaveBeenCalled();
});
+ it('should re-align the ink bar when the tabs list change', () => {
+ const inkBar = fixture.componentInstance.tabNavBar._inkBar;
+
+ spyOn(inkBar, 'alignToElement');
+
+ fixture.componentInstance.tabs = [1, 2, 3, 4];
+ fixture.detectChanges();
+
+ expect(inkBar.alignToElement).toHaveBeenCalled();
+ });
+
+ it('should re-align the ink bar when the tab labels change the width', done => {
+ const inkBar = fixture.componentInstance.tabNavBar._inkBar;
+
+ const spy = spyOn(inkBar, 'alignToElement').and.callFake(() => {
+ expect(spy.calls.any()).toBe(true);
+ done();
+ });
+
+ fixture.componentInstance.label = 'label change';
+ fixture.detectChanges();
+
+ expect(spy.calls.any()).toBe(false);
+ });
+
it('should re-align the ink bar when the window is resized', fakeAsync(() => {
const inkBar = fixture.componentInstance.tabNavBar._inkBar;
@@ -97,15 +121,21 @@ describe('MdTabNavBar', () => {
selector: 'test-app',
template: `
`
})
class SimpleTabNavBarTestApp {
@ViewChild(MdTabNavBar) tabNavBar: MdTabNavBar;
+ label = '';
+ tabs = [0, 1, 2];
+
activeIndex = 0;
}
diff --git a/src/lib/tabs/tab-nav-bar/tab-nav-bar.ts b/src/lib/tabs/tab-nav-bar/tab-nav-bar.ts
index 3ca54f6f46d..2ec833080d6 100644
--- a/src/lib/tabs/tab-nav-bar/tab-nav-bar.ts
+++ b/src/lib/tabs/tab-nav-bar/tab-nav-bar.ts
@@ -1,25 +1,26 @@
import {
- Component,
- Input,
- ViewChild,
- ElementRef,
- ViewEncapsulation,
- Directive,
- NgZone,
- Inject,
- Optional,
- OnDestroy,
AfterContentInit,
+ Component,
+ Directive,
+ ElementRef,
+ Inject,
+ Input,
+ NgZone,
+ OnDestroy,
+ Optional,
+ ViewChild,
+ ViewEncapsulation
} from '@angular/core';
import {MdInkBar} from '../ink-bar';
import {MdRipple} from '../../core/ripple/index';
import {ViewportRuler} from '../../core/overlay/position/viewport-ruler';
-import {MD_RIPPLE_GLOBAL_OPTIONS, RippleGlobalOptions, Dir, Platform} from '../../core';
+import {Dir, MD_RIPPLE_GLOBAL_OPTIONS, Platform, RippleGlobalOptions} from '../../core';
import {Observable} from 'rxjs/Observable';
-import {Subscription} from 'rxjs/Subscription';
import 'rxjs/add/operator/auditTime';
+import 'rxjs/add/operator/takeUntil';
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/merge';
+import {Subject} from 'rxjs/Subject';
/**
* Navigation component matching the styles of the tab group header.
@@ -34,8 +35,8 @@ import 'rxjs/add/observable/merge';
encapsulation: ViewEncapsulation.None,
})
export class MdTabNavBar implements AfterContentInit, OnDestroy {
- /** Combines listeners that will re-align the ink bar whenever they're invoked. */
- private _realignInkBar: Subscription = null;
+ /** Subject that emits when the component has been destroyed. */
+ private _onDestroy = new Subject
();
_activeLinkChanged: boolean;
_activeLinkElement: ElementRef;
@@ -51,13 +52,15 @@ export class MdTabNavBar implements AfterContentInit, OnDestroy {
}
ngAfterContentInit(): void {
- this._realignInkBar = this._ngZone.runOutsideAngular(() => {
+ this._ngZone.runOutsideAngular(() => {
let dirChange = this._dir ? this._dir.dirChange : Observable.of(null);
let resize = typeof window !== 'undefined' ?
Observable.fromEvent(window, 'resize').auditTime(10) :
Observable.of(null);
- return Observable.merge(dirChange, resize).subscribe(() => this._alignInkBar());
+ return Observable.merge(dirChange, resize)
+ .takeUntil(this._onDestroy)
+ .subscribe(() => this._alignInkBar());
});
}
@@ -70,14 +73,11 @@ export class MdTabNavBar implements AfterContentInit, OnDestroy {
}
ngOnDestroy() {
- if (this._realignInkBar) {
- this._realignInkBar.unsubscribe();
- this._realignInkBar = null;
- }
+ this._onDestroy.next();
}
/** Aligns the ink bar to the active link. */
- private _alignInkBar(): void {
+ _alignInkBar(): void {
if (this._activeLinkElement) {
this._inkBar.alignToElement(this._activeLinkElement.nativeElement);
}
diff --git a/tools/gulp/packaging/rollup-helpers.ts b/tools/gulp/packaging/rollup-helpers.ts
index b1dc4415d24..cbed6e3fc58 100644
--- a/tools/gulp/packaging/rollup-helpers.ts
+++ b/tools/gulp/packaging/rollup-helpers.ts
@@ -42,6 +42,7 @@ const ROLLUP_GLOBALS = {
'rxjs/add/operator/share': 'Rx.Observable.prototype',
'rxjs/add/operator/startWith': 'Rx.Observable.prototype',
'rxjs/add/operator/switchMap': 'Rx.Observable.prototype',
+ 'rxjs/add/operator/takeUntil': 'Rx.Observable.prototype',
'rxjs/add/operator/toPromise': 'Rx.Observable.prototype',
'rxjs/BehaviorSubject': 'Rx',
'rxjs/Observable': 'Rx',