@@ -15,6 +15,7 @@ import {
15
15
PositionStrategy ,
16
16
ScrollStrategy ,
17
17
} from '@angular/cdk/overlay' ;
18
+ import { TemplatePortal } from '@angular/cdk/portal' ;
18
19
import { DOCUMENT } from '@angular/common' ;
19
20
import { filter , take , switchMap , delay , tap , map } from 'rxjs/operators' ;
20
21
import {
@@ -29,6 +30,7 @@ import {
29
30
NgZone ,
30
31
OnDestroy ,
31
32
Optional ,
33
+ ViewContainerRef ,
32
34
} from '@angular/core' ;
33
35
import { ViewportRuler } from '@angular/cdk/scrolling' ;
34
36
import { ControlValueAccessor , NG_VALUE_ACCESSOR } from '@angular/forms' ;
@@ -115,9 +117,9 @@ export function getMatAutocompleteMissingPanelError(): Error {
115
117
} )
116
118
export class MatAutocompleteTrigger implements ControlValueAccessor , OnDestroy {
117
119
private _overlayRef : OverlayRef | null ;
120
+ private _portal : TemplatePortal ;
118
121
private _componentDestroyed = false ;
119
122
private _autocompleteDisabled = false ;
120
- private _autocomplete : MatAutocomplete ;
121
123
private _scrollStrategy : ( ) => ScrollStrategy ;
122
124
123
125
/** Old value of the native input. Used to work around issues with the `input` event on IE. */
@@ -130,7 +132,7 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
130
132
private _manuallyFloatingLabel = false ;
131
133
132
134
/** The subscription for closing actions (some are bound to document). */
133
- private _closingActionsSubscription = Subscription . EMPTY ;
135
+ private _closingActionsSubscription : Subscription ;
134
136
135
137
/** Subscription to viewport size changes. */
136
138
private _viewportSubscription = Subscription . EMPTY ;
@@ -164,12 +166,7 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
164
166
_onTouched = ( ) => { } ;
165
167
166
168
/** The autocomplete panel to be attached to this trigger. */
167
- @Input ( 'matAutocomplete' )
168
- get autocomplete ( ) : MatAutocomplete { return this . _autocomplete ; }
169
- set autocomplete ( value : MatAutocomplete ) {
170
- this . _autocomplete = value ;
171
- this . _detachOverlay ( ) ;
172
- }
169
+ @Input ( 'matAutocomplete' ) autocomplete : MatAutocomplete ;
173
170
174
171
/**
175
172
* Reference relative to which to position the autocomplete panel.
@@ -193,8 +190,8 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
193
190
this . _autocompleteDisabled = coerceBooleanProperty ( value ) ;
194
191
}
195
192
196
- constructor ( private _element : ElementRef < HTMLInputElement > ,
197
- private _overlay : Overlay ,
193
+ constructor ( private _element : ElementRef < HTMLInputElement > , private _overlay : Overlay ,
194
+ private _viewContainerRef : ViewContainerRef ,
198
195
private _zone : NgZone ,
199
196
private _changeDetectorRef : ChangeDetectorRef ,
200
197
@Inject ( MAT_AUTOCOMPLETE_SCROLL_STRATEGY ) scrollStrategy : any ,
@@ -249,9 +246,12 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
249
246
this . autocomplete . closed . emit ( ) ;
250
247
}
251
248
252
- this . autocomplete . _isOpen = false ;
253
- this . _detachOverlay ( ) ;
249
+ this . autocomplete . _isOpen = this . _overlayAttached = false ;
254
250
251
+ if ( this . _overlayRef && this . _overlayRef . hasAttached ( ) ) {
252
+ this . _overlayRef . detach ( ) ;
253
+ this . _closingActionsSubscription . unsubscribe ( ) ;
254
+ }
255
255
256
256
// Note that in some cases this can end up being called after the component is destroyed.
257
257
// Add a check to ensure that we don't try to run change detection on a destroyed view.
@@ -570,6 +570,7 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
570
570
}
571
571
572
572
if ( ! this . _overlayRef ) {
573
+ this . _portal = new TemplatePortal ( this . autocomplete . template , this . _viewContainerRef ) ;
573
574
this . _overlayRef = this . _overlay . create ( this . _getOverlayConfig ( ) ) ;
574
575
575
576
// Use the `keydownEvents` in order to take advantage of
@@ -596,7 +597,7 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
596
597
}
597
598
598
599
if ( this . _overlayRef && ! this . _overlayRef . hasAttached ( ) ) {
599
- this . _overlayRef . attach ( this . autocomplete . _portal ) ;
600
+ this . _overlayRef . attach ( this . _portal ) ;
600
601
this . _closingActionsSubscription = this . _subscribeToClosingActions ( ) ;
601
602
}
602
603
@@ -612,14 +613,6 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
612
613
}
613
614
}
614
615
615
- private _detachOverlay ( ) {
616
- this . _overlayAttached = false ;
617
- this . _closingActionsSubscription . unsubscribe ( ) ;
618
- if ( this . _overlayRef ) {
619
- this . _overlayRef . detach ( ) ;
620
- }
621
- }
622
-
623
616
private _getOverlayConfig ( ) : OverlayConfig {
624
617
return new OverlayConfig ( {
625
618
positionStrategy : this . _getOverlayPosition ( ) ,
0 commit comments