@@ -32,6 +32,15 @@ import {Focusable} from '../core/a11y/focus-key-manager';
32
32
import { MdListOption } from './list-option' ;
33
33
import { CanDisable , mixinDisabled } from '../core/common-behaviors/disabled' ;
34
34
import { RxChain , switchMap , first , filter } from '../core/rxjs/index' ;
35
+ import 'rxjs/add/observable/merge' ;
36
+ import 'rxjs/add/observable/fromEvent' ;
37
+ import 'rxjs/add/operator/filter' ;
38
+ import 'rxjs/add/operator/switchMap' ;
39
+ import 'rxjs/add/observable/of' ;
40
+ import { merge } from 'rxjs/operator/merge' ;
41
+ import { Observable } from 'rxjs/Observable' ;
42
+ import 'rxjs/add/operator/switchMap' ;
43
+ import 'rxjs/add/operator/startWith' ;
35
44
36
45
export class MdSelectionListBase { }
37
46
export const _MdSelectionListMixinBase = mixinDisabled ( MdSelectionListBase ) ;
@@ -59,15 +68,15 @@ export class MdSelectionList extends _MdSelectionListMixinBase
59
68
/** Tab index for the selection-list. */
60
69
_tabIndex = 0 ;
61
70
62
- /** Track which options we're listening to for focus/destruction. */
63
- private _subscribed : WeakMap < MdListOption , boolean > = new WeakMap ( ) ;
64
-
65
71
/** Subscription to tabbing out from the selection-list. */
66
72
private _tabOutSubscription : Subscription ;
67
73
68
74
/** Subscription to option changes from the selection-list. */
69
75
private _optionsChangeSubscription : Subscription ;
70
76
77
+ private _optionsChangeSubscriptionOnFocus : Subscription ;
78
+ private _optionsChangeSubscriptionDestory : Subscription ;
79
+
71
80
/** The FocusKeyManager which handles focus. */
72
81
_keyManager : FocusKeyManager ;
73
82
@@ -96,13 +105,8 @@ export class MdSelectionList extends _MdSelectionListMixinBase
96
105
this . _tabIndex = - 1 ;
97
106
}
98
107
99
- // Go ahead and subscribe all of the initial options
100
- this . _subscribeOptions ( this . options ) ;
101
- // When the list changes, re-subscribe
102
- this . _optionsChangeSubscription =
103
- this . options . changes . subscribe ( ( options : QueryList < MdListOption > ) => {
104
- this . _subscribeOptions ( options ) ;
105
- } ) ;
108
+ this . _optionsChangeSubscriptionOnFocus = this . onFocusSubscription ( ) ;
109
+ this . _optionsChangeSubscriptionDestory = this . onDestorySubscription ( ) ;
106
110
}
107
111
108
112
ngOnDestroy ( ) : void {
@@ -119,6 +123,32 @@ export class MdSelectionList extends _MdSelectionListMixinBase
119
123
this . _element . nativeElement . focus ( ) ;
120
124
}
121
125
126
+ onDestorySubscription ( ) : Subscription {
127
+ return this . options . changes . startWith ( this . options ) . switchMap ( ( options ) => {
128
+ return Observable . merge ( ...options . map ( option => option . destroy ) ) ;
129
+ } ) . subscribe ( e => {
130
+ let optionIndex : number = this . options . toArray ( ) . indexOf ( e . option ) ;
131
+ if ( e . option . _hasFocus ) {
132
+ // Check whether the option is the last item
133
+ if ( optionIndex < this . options . length - 1 ) {
134
+ this . _keyManager . setActiveItem ( optionIndex ) ;
135
+ } else if ( optionIndex - 1 >= 0 ) {
136
+ this . _keyManager . setActiveItem ( optionIndex - 1 ) ;
137
+ }
138
+ }
139
+ e . option . destroy . unsubscribe ( ) ;
140
+ } ) ;
141
+ }
142
+
143
+ onFocusSubscription ( ) : Subscription {
144
+ return this . options . changes . startWith ( this . options ) . switchMap ( ( options ) => {
145
+ return Observable . merge ( ...options . map ( option => option . onFocus ) ) ;
146
+ } ) . subscribe ( e => {
147
+ let optionIndex : number = this . options . toArray ( ) . indexOf ( e . option ) ;
148
+ this . _keyManager . updateActiveItemIndex ( optionIndex ) ;
149
+ } ) ;
150
+ }
151
+
122
152
/** Passes relevant key presses to our key manager. */
123
153
keydown ( event : KeyboardEvent ) {
124
154
switch ( event . keyCode ) {
@@ -145,56 +175,6 @@ export class MdSelectionList extends _MdSelectionListMixinBase
145
175
}
146
176
}
147
177
148
- /**
149
- * Iterate through the list of options and add them to our list of
150
- * subscribed options.
151
- *
152
- * @param options The list of options to be subscribed.
153
- */
154
- protected _subscribeOptions ( options : QueryList < MdListOption > ) : void {
155
- options . forEach ( option => this . _addOption ( option ) ) ;
156
- }
157
-
158
- /**
159
- * Add a specific option to our subscribed list. If the option has
160
- * already been subscribed, this ensures it is only subscribed
161
- * once.
162
- *
163
- * @param option The option to be subscribed (or checked for existing
164
- * subscription).
165
- */
166
- protected _addOption ( option : MdListOption ) {
167
- // If we've already been subscribed to a parent, do nothing
168
- if ( this . _subscribed . has ( option ) ) {
169
- return ;
170
- }
171
-
172
- // Watch for focus events outside of the keyboard navigation
173
- option . onFocus . subscribe ( ( ) => {
174
- let optionIndex : number = this . options . toArray ( ) . indexOf ( option ) ;
175
- this . _keyManager . updateActiveItemIndex ( optionIndex ) ;
176
- } ) ;
177
-
178
- // On destroy, remove the item from our list, and check focus
179
- option . destroy . subscribe ( ( ) => {
180
- let optionIndex : number = this . options . toArray ( ) . indexOf ( option ) ;
181
-
182
- if ( option . _hasFocus ) {
183
- // Check whether the option is the last item
184
- if ( optionIndex < this . options . length - 1 ) {
185
- this . _keyManager . setActiveItem ( optionIndex ) ;
186
- } else if ( optionIndex - 1 >= 0 ) {
187
- this . _keyManager . setActiveItem ( optionIndex - 1 ) ;
188
- }
189
- }
190
-
191
- this . _subscribed . delete ( option ) ;
192
- option . destroy . unsubscribe ( ) ;
193
- } ) ;
194
-
195
- this . _subscribed . set ( option , true ) ;
196
- }
197
-
198
178
/**
199
179
* Utility to ensure all indexes are valid.
200
180
*
0 commit comments