1
- import { Directive , ElementRef , Input , ViewContainerRef , OnDestroy } from '@angular/core' ;
1
+ import {
2
+ Directive , ElementRef , Input , ViewContainerRef , Optional , OnDestroy
3
+ } from '@angular/core' ;
4
+ import { NgControl } from '@angular/forms' ;
2
5
import { Overlay , OverlayRef , OverlayState , TemplatePortal } from '../core' ;
3
6
import { MdAutocomplete } from './autocomplete' ;
4
7
import { PositionStrategy } from '../core/overlay/position/position-strategy' ;
5
8
import { Observable } from 'rxjs/Observable' ;
6
9
import { Subscription } from 'rxjs/Subscription' ;
7
10
import 'rxjs/add/observable/merge' ;
11
+ import { MdOptionSelectEvent } from '../core/option/option' ;
8
12
9
13
/** The panel needs a slight y-offset to ensure the input underline displays. */
10
14
export const MD_AUTOCOMPLETE_PANEL_OFFSET = 6 ;
@@ -23,11 +27,15 @@ export class MdAutocompleteTrigger implements OnDestroy {
23
27
/** The subscription to events that close the autocomplete panel. */
24
28
private _closingActionsSubscription : Subscription ;
25
29
30
+ /** The subscription to changes in the options list. */
31
+ private _optionChangesSubscription : Subscription ;
32
+
26
33
/* The autocomplete panel to be attached to this trigger. */
27
34
@Input ( 'mdAutocomplete' ) autocomplete : MdAutocomplete ;
28
35
29
36
constructor ( private _element : ElementRef , private _overlay : Overlay ,
30
- private _viewContainerRef : ViewContainerRef ) { }
37
+ private _viewContainerRef : ViewContainerRef ,
38
+ @Optional ( ) private _controlDir : NgControl ) { }
31
39
32
40
ngOnDestroy ( ) { this . _destroyPanel ( ) ; }
33
41
@@ -44,8 +52,9 @@ export class MdAutocompleteTrigger implements OnDestroy {
44
52
45
53
if ( ! this . _overlayRef . hasAttached ( ) ) {
46
54
this . _overlayRef . attach ( this . _portal ) ;
47
- this . _closingActionsSubscription =
48
- this . panelClosingActions . subscribe ( ( ) => this . closePanel ( ) ) ;
55
+ this . _resetClosingActionSub ( ) ;
56
+ this . _optionChangesSubscription =
57
+ this . autocomplete . options . changes . subscribe ( ( ) => this . _resetClosingActionSub ( ) ) ;
49
58
}
50
59
51
60
this . _panelOpen = true ;
@@ -58,6 +67,7 @@ export class MdAutocompleteTrigger implements OnDestroy {
58
67
}
59
68
60
69
this . _closingActionsSubscription . unsubscribe ( ) ;
70
+ this . _optionChangesSubscription . unsubscribe ( ) ;
61
71
this . _panelOpen = false ;
62
72
}
63
73
@@ -75,6 +85,20 @@ export class MdAutocompleteTrigger implements OnDestroy {
75
85
return this . autocomplete . options . map ( option => option . onSelect ) ;
76
86
}
77
87
88
+ /**
89
+ * Drops the current closing action subscription and re-creates it.
90
+ * Used whenever the option list changes to ensure that new options
91
+ * can be selected properly.
92
+ */
93
+ private _resetClosingActionSub ( ) {
94
+ if ( this . _closingActionsSubscription ) {
95
+ this . _closingActionsSubscription . unsubscribe ( ) ;
96
+ }
97
+
98
+ this . _closingActionsSubscription =
99
+ this . panelClosingActions . subscribe ( event => this . _setValueAndClose ( event ) ) ;
100
+ }
101
+
78
102
/** Destroys the autocomplete suggestion panel. */
79
103
private _destroyPanel ( ) : void {
80
104
if ( this . _overlayRef ) {
@@ -84,6 +108,23 @@ export class MdAutocompleteTrigger implements OnDestroy {
84
108
}
85
109
}
86
110
111
+ /**
112
+ * This method closes the panel, and if a value is specified, also sets the associated
113
+ * control to that value. It will also mark the control as dirty if this interaction
114
+ * stemmed from the user.
115
+ */
116
+ private _setValueAndClose ( event : MdOptionSelectEvent | null ) : void {
117
+ if ( event ) {
118
+ // TODO(kara): revisit animation once floating placeholder is toggle-able
119
+ this . _controlDir . control . setValue ( event . source . value ) ;
120
+ if ( event . isUserInput ) {
121
+ this . _controlDir . control . markAsDirty ( ) ;
122
+ }
123
+ }
124
+
125
+ this . closePanel ( ) ;
126
+ }
127
+
87
128
private _createOverlay ( ) : void {
88
129
this . _portal = new TemplatePortal ( this . autocomplete . template , this . _viewContainerRef ) ;
89
130
this . _overlayRef = this . _overlay . create ( this . _getOverlayConfig ( ) ) ;
0 commit comments