@@ -12,13 +12,20 @@ import {
1212 AfterContentChecked ,
1313 AfterContentInit ,
1414 OnDestroy ,
15+ NgZone ,
1516} from '@angular/core' ;
1617import { RIGHT_ARROW , LEFT_ARROW , ENTER , Dir , LayoutDirection } from '../core' ;
1718import { MdTabLabelWrapper } from './tab-label-wrapper' ;
1819import { MdInkBar } from './ink-bar' ;
1920import { Subscription } from 'rxjs/Subscription' ;
21+ import { Observable } from 'rxjs/Observable' ;
2022import { applyCssTransform } from '../core/style/apply-transform' ;
2123import 'rxjs/add/operator/map' ;
24+ import 'rxjs/add/operator/auditTime' ;
25+ import 'rxjs/add/observable/of' ;
26+ import 'rxjs/add/observable/merge' ;
27+ import 'rxjs/add/operator/startWith' ;
28+
2229
2330/**
2431 * The directions that scrolling can go in when the header's tabs exceed the header width. 'After'
@@ -68,8 +75,8 @@ export class MdTabHeader implements AfterContentChecked, AfterContentInit, OnDes
6875 /** Whether the header should scroll to the selected index after the view has been checked. */
6976 private _selectedIndexChanged = false ;
7077
71- /** Subscription to changes in the layout direction . */
72- private _directionChange : Subscription ;
78+ /** Combines listeners that will re-align the ink bar whenever they're invoked . */
79+ private _realignInkBar : Subscription = null ;
7380
7481 /** Whether the controls for pagination should be displayed */
7582 _showPaginationControls = false ;
@@ -92,21 +99,25 @@ export class MdTabHeader implements AfterContentChecked, AfterContentInit, OnDes
9299 private _selectedIndex : number = 0 ;
93100
94101 /** The index of the active tab. */
95- @Input ( ) set selectedIndex ( value : number ) {
102+ @Input ( )
103+ get selectedIndex ( ) : number { return this . _selectedIndex ; }
104+ set selectedIndex ( value : number ) {
96105 this . _selectedIndexChanged = this . _selectedIndex != value ;
97106
98107 this . _selectedIndex = value ;
99108 this . _focusIndex = value ;
100109 }
101- get selectedIndex ( ) : number { return this . _selectedIndex ; }
102110
103111 /** Event emitted when the option is selected. */
104112 @Output ( ) selectFocusedIndex = new EventEmitter ( ) ;
105113
106114 /** Event emitted when a label is focused. */
107115 @Output ( ) indexFocused = new EventEmitter ( ) ;
108116
109- constructor ( private _elementRef : ElementRef , @Optional ( ) private _dir : Dir ) { }
117+ constructor (
118+ private _elementRef : ElementRef ,
119+ private _ngZone : NgZone ,
120+ @Optional ( ) private _dir : Dir ) { }
110121
111122 ngAfterContentChecked ( ) : void {
112123 // If the number of tab labels have changed, check if scrolling should be enabled
@@ -150,17 +161,23 @@ export class MdTabHeader implements AfterContentChecked, AfterContentInit, OnDes
150161 * Aligns the ink bar to the selected tab on load.
151162 */
152163 ngAfterContentInit ( ) {
153- this . _alignInkBarToSelectedTab ( ) ;
154-
155- if ( this . _dir ) {
156- this . _directionChange = this . _dir . dirChange . subscribe ( ( ) => this . _alignInkBarToSelectedTab ( ) ) ;
157- }
164+ this . _realignInkBar = this . _ngZone . runOutsideAngular ( ( ) => {
165+ let dirChange = this . _dir ? this . _dir . dirChange : Observable . of ( null ) ;
166+ let resize = typeof window !== 'undefined' ?
167+ Observable . fromEvent ( window , 'resize' ) . auditTime ( 10 ) :
168+ Observable . of ( null ) ;
169+
170+ return Observable . merge ( dirChange , resize ) . startWith ( null ) . subscribe ( ( ) => {
171+ this . _updatePagination ( ) ;
172+ this . _alignInkBarToSelectedTab ( ) ;
173+ } ) ;
174+ } ) ;
158175 }
159176
160177 ngOnDestroy ( ) {
161- if ( this . _directionChange ) {
162- this . _directionChange . unsubscribe ( ) ;
163- this . _directionChange = null ;
178+ if ( this . _realignInkBar ) {
179+ this . _realignInkBar . unsubscribe ( ) ;
180+ this . _realignInkBar = null ;
164181 }
165182 }
166183
0 commit comments