@@ -18,7 +18,7 @@ import {
18
18
ScrollStrategy ,
19
19
ViewportRuler ,
20
20
} from '@angular/cdk/overlay' ;
21
- import { filter , first , startWith } from '@angular/cdk/rxjs' ;
21
+ import { filter , first , startWith , takeUntil , RxChain } from '@angular/cdk/rxjs' ;
22
22
import {
23
23
AfterContentInit ,
24
24
Attribute ,
@@ -67,7 +67,6 @@ import {MatFormField, MatFormFieldControl} from '@angular/material/form-field';
67
67
import { Observable } from 'rxjs/Observable' ;
68
68
import { merge } from 'rxjs/observable/merge' ;
69
69
import { Subject } from 'rxjs/Subject' ;
70
- import { Subscription } from 'rxjs/Subscription' ;
71
70
import { fadeInContent , transformPanel } from './select-animations' ;
72
71
import {
73
72
getMatSelectDynamicMultipleError ,
@@ -193,15 +192,6 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
193
192
/** Whether or not the overlay panel is open. */
194
193
private _panelOpen = false ;
195
194
196
- /** Subscriptions to option events. */
197
- private _optionSubscription = Subscription . EMPTY ;
198
-
199
- /** Subscription to changes in the option list. */
200
- private _changeSubscription = Subscription . EMPTY ;
201
-
202
- /** Subscription to tab events while overlay is focused. */
203
- private _tabSubscription = Subscription . EMPTY ;
204
-
205
195
/** Whether filling out the select is required in the form. */
206
196
private _required : boolean = false ;
207
197
@@ -220,6 +210,9 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
220
210
/** Unique id for this input. */
221
211
private _uid = `mat-select-${ nextUniqueId ++ } ` ;
222
212
213
+ /** Emits whenever the component is destroyed. */
214
+ private _destroy = new Subject < void > ( ) ;
215
+
223
216
/** The last measured value for the trigger's client bounding rect. */
224
217
_triggerRect : ClientRect ;
225
218
@@ -453,10 +446,13 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
453
446
ngAfterContentInit ( ) {
454
447
this . _initKeyManager ( ) ;
455
448
456
- this . _changeSubscription = startWith . call ( this . options . changes , null ) . subscribe ( ( ) => {
457
- this . _resetOptions ( ) ;
458
- this . _initializeSelection ( ) ;
459
- } ) ;
449
+ RxChain . from ( this . options . changes )
450
+ . call ( startWith , null )
451
+ . call ( takeUntil , this . _destroy )
452
+ . subscribe ( ( ) => {
453
+ this . _resetOptions ( ) ;
454
+ this . _initializeSelection ( ) ;
455
+ } ) ;
460
456
}
461
457
462
458
ngDoCheck ( ) {
@@ -466,9 +462,8 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
466
462
}
467
463
468
464
ngOnDestroy ( ) {
469
- this . _dropSubscriptions ( ) ;
470
- this . _changeSubscription . unsubscribe ( ) ;
471
- this . _tabSubscription . unsubscribe ( ) ;
465
+ this . _destroy . next ( ) ;
466
+ this . _destroy . complete ( ) ;
472
467
}
473
468
474
469
/** Toggles the overlay panel open or closed. */
@@ -493,7 +488,7 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
493
488
this . _changeDetectorRef . markForCheck ( ) ;
494
489
495
490
// Set the font size on the panel element once it exists.
496
- first . call ( this . _ngZone . onStable ) . subscribe ( ( ) => {
491
+ first . call ( this . _ngZone . onStable . asObservable ( ) ) . subscribe ( ( ) => {
497
492
if ( this . _triggerFontSize && this . overlayDir . overlayRef &&
498
493
this . overlayDir . overlayRef . overlayElement ) {
499
494
this . overlayDir . overlayRef . overlayElement . style . fontSize = `${ this . _triggerFontSize } px` ;
@@ -621,13 +616,6 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
621
616
this . _keyManager . activeItem . _selectViaInteraction ( ) ;
622
617
} else {
623
618
this . _keyManager . onKeydown ( event ) ;
624
-
625
- // TODO(crisbeto): get rid of the Promise.resolve when #6441 gets in.
626
- Promise . resolve ( ) . then ( ( ) => {
627
- if ( this . panelOpen ) {
628
- this . _scrollActiveOptionIntoView ( ) ;
629
- }
630
- } ) ;
631
619
}
632
620
}
633
621
@@ -781,28 +769,32 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
781
769
/** Sets up a key manager to listen to keyboard events on the overlay panel. */
782
770
private _initKeyManager ( ) {
783
771
this . _keyManager = new ActiveDescendantKeyManager < MatOption > ( this . options ) . withTypeAhead ( ) ;
784
- this . _tabSubscription = this . _keyManager . tabOut . subscribe ( ( ) => this . close ( ) ) ;
772
+
773
+ takeUntil . call ( this . _keyManager . tabOut , this . _destroy )
774
+ . subscribe ( ( ) => this . close ( ) ) ;
775
+
776
+ RxChain . from ( this . _keyManager . change )
777
+ . call ( takeUntil , this . _destroy )
778
+ . call ( filter , ( ) => this . _panelOpen && ! ! this . panel )
779
+ . subscribe ( ( ) => this . _scrollActiveOptionIntoView ( ) ) ;
785
780
}
786
781
787
782
/** Drops current option subscriptions and IDs and resets from scratch. */
788
783
private _resetOptions ( ) : void {
789
- this . _dropSubscriptions ( ) ;
790
- this . _listenToOptions ( ) ;
791
- this . _setOptionIds ( ) ;
792
- this . _setOptionMultiple ( ) ;
793
- this . _setOptionDisableRipple ( ) ;
794
- }
795
-
796
- /** Listens to user-generated selection events on each option. */
797
- private _listenToOptions ( ) : void {
798
- this . _optionSubscription = filter . call ( this . optionSelectionChanges ,
799
- event => event . isUserInput ) . subscribe ( event => {
784
+ RxChain . from ( this . optionSelectionChanges )
785
+ . call ( takeUntil , merge ( this . _destroy , this . options . changes ) )
786
+ . call ( filter , event => event . isUserInput )
787
+ . subscribe ( event => {
800
788
this . _onSelect ( event . source ) ;
801
789
802
790
if ( ! this . multiple ) {
803
791
this . close ( ) ;
804
792
}
805
793
} ) ;
794
+
795
+ this . _setOptionIds ( ) ;
796
+ this . _setOptionMultiple ( ) ;
797
+ this . _setOptionDisableRipple ( ) ;
806
798
}
807
799
808
800
/** Invoked when an option is clicked. */
@@ -848,11 +840,6 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
848
840
}
849
841
}
850
842
851
- /** Unsubscribes from all option subscriptions. */
852
- private _dropSubscriptions ( ) : void {
853
- this . _optionSubscription . unsubscribe ( ) ;
854
- }
855
-
856
843
/** Emits change event to set the model value. */
857
844
private _propagateChanges ( fallbackValue ?: any ) : void {
858
845
let valueToEmit : any = null ;
0 commit comments