Skip to content

Commit 733c8ee

Browse files
committed
Revert "fix(autocomplete): update template when changing autocomplete in trigger" (#14398)
* Revert "Revert "fix(autocomplete): auto-highlighted first option not display correctly if the floating label is disabled" (#14396)" This reverts commit aa17fbd. * Revert "fix(drag-drop): error on touch end (#14392)" This reverts commit 53cecbb. * Revert "fix(menu): reduce specificity of icon selector (#14389)" This reverts commit 74e945a. * Revert "fix(drag-drop): throw better error when attaching to non-element node (#14221)" This reverts commit 31f0e6d. * Revert "fix(autocomplete): auto-highlighted first option not display correctly if the floating label is disabled (#13774)" This reverts commit c99c512. * Revert "fix(autocomplete): update template when changing autocomplete in trigger (#13814)" This reverts commit 904a5ea.
1 parent 753eae5 commit 733c8ee

File tree

3 files changed

+15
-80
lines changed

3 files changed

+15
-80
lines changed

src/lib/autocomplete/autocomplete-trigger.ts

+14-21
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
PositionStrategy,
1616
ScrollStrategy,
1717
} from '@angular/cdk/overlay';
18+
import {TemplatePortal} from '@angular/cdk/portal';
1819
import {DOCUMENT} from '@angular/common';
1920
import {filter, take, switchMap, delay, tap, map} from 'rxjs/operators';
2021
import {
@@ -29,6 +30,7 @@ import {
2930
NgZone,
3031
OnDestroy,
3132
Optional,
33+
ViewContainerRef,
3234
} from '@angular/core';
3335
import {ViewportRuler} from '@angular/cdk/scrolling';
3436
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
@@ -115,9 +117,9 @@ export function getMatAutocompleteMissingPanelError(): Error {
115117
})
116118
export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
117119
private _overlayRef: OverlayRef | null;
120+
private _portal: TemplatePortal;
118121
private _componentDestroyed = false;
119122
private _autocompleteDisabled = false;
120-
private _autocomplete: MatAutocomplete;
121123
private _scrollStrategy: () => ScrollStrategy;
122124

123125
/** 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 {
130132
private _manuallyFloatingLabel = false;
131133

132134
/** The subscription for closing actions (some are bound to document). */
133-
private _closingActionsSubscription = Subscription.EMPTY;
135+
private _closingActionsSubscription: Subscription;
134136

135137
/** Subscription to viewport size changes. */
136138
private _viewportSubscription = Subscription.EMPTY;
@@ -164,12 +166,7 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
164166
_onTouched = () => {};
165167

166168
/** 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;
173170

174171
/**
175172
* Reference relative to which to position the autocomplete panel.
@@ -193,8 +190,8 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
193190
this._autocompleteDisabled = coerceBooleanProperty(value);
194191
}
195192

196-
constructor(private _element: ElementRef<HTMLInputElement>,
197-
private _overlay: Overlay,
193+
constructor(private _element: ElementRef<HTMLInputElement>, private _overlay: Overlay,
194+
private _viewContainerRef: ViewContainerRef,
198195
private _zone: NgZone,
199196
private _changeDetectorRef: ChangeDetectorRef,
200197
@Inject(MAT_AUTOCOMPLETE_SCROLL_STRATEGY) scrollStrategy: any,
@@ -249,9 +246,12 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
249246
this.autocomplete.closed.emit();
250247
}
251248

252-
this.autocomplete._isOpen = false;
253-
this._detachOverlay();
249+
this.autocomplete._isOpen = this._overlayAttached = false;
254250

251+
if (this._overlayRef && this._overlayRef.hasAttached()) {
252+
this._overlayRef.detach();
253+
this._closingActionsSubscription.unsubscribe();
254+
}
255255

256256
// Note that in some cases this can end up being called after the component is destroyed.
257257
// 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 {
570570
}
571571

572572
if (!this._overlayRef) {
573+
this._portal = new TemplatePortal(this.autocomplete.template, this._viewContainerRef);
573574
this._overlayRef = this._overlay.create(this._getOverlayConfig());
574575

575576
// Use the `keydownEvents` in order to take advantage of
@@ -596,7 +597,7 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
596597
}
597598

598599
if (this._overlayRef && !this._overlayRef.hasAttached()) {
599-
this._overlayRef.attach(this.autocomplete._portal);
600+
this._overlayRef.attach(this._portal);
600601
this._closingActionsSubscription = this._subscribeToClosingActions();
601602
}
602603

@@ -612,14 +613,6 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
612613
}
613614
}
614615

615-
private _detachOverlay() {
616-
this._overlayAttached = false;
617-
this._closingActionsSubscription.unsubscribe();
618-
if (this._overlayRef) {
619-
this._overlayRef.detach();
620-
}
621-
}
622-
623616
private _getOverlayConfig(): OverlayConfig {
624617
return new OverlayConfig({
625618
positionStrategy: this._getOverlayPosition(),

src/lib/autocomplete/autocomplete.spec.ts

-47
Original file line numberDiff line numberDiff line change
@@ -2233,35 +2233,6 @@ describe('MatAutocomplete', () => {
22332233
expect(formControl.value).toBe('Cal', 'Expected new value to be propagated to model');
22342234
}));
22352235

2236-
it('should work when dynamically changing the autocomplete', () => {
2237-
const fixture = createComponent(DynamicallyChangingAutocomplete);
2238-
fixture.detectChanges();
2239-
const input = fixture.debugElement.query(By.css('input')).nativeElement;
2240-
2241-
dispatchFakeEvent(input, 'focusin');
2242-
fixture.detectChanges();
2243-
2244-
expect(overlayContainerElement.textContent).toContain('First',
2245-
`Expected panel to display the option of the first autocomplete.`);
2246-
expect(overlayContainerElement.textContent).not.toContain('Second',
2247-
`Expected panel to not display the option of the second autocomplete.`);
2248-
2249-
dispatchFakeEvent(document, 'click');
2250-
fixture.detectChanges();
2251-
2252-
fixture.componentInstance.trigger.autocomplete = fixture.componentInstance.autoTow;
2253-
fixture.detectChanges();
2254-
2255-
dispatchFakeEvent(input, 'focusin');
2256-
fixture.detectChanges();
2257-
2258-
expect(overlayContainerElement.textContent).not.toContain('First',
2259-
`Expected panel to not display the option of the first autocomplete.`);
2260-
expect(overlayContainerElement.textContent).toContain('Second',
2261-
`Expected panel to display the option of the second autocomplete.`);
2262-
2263-
});
2264-
22652236
});
22662237

22672238
@Component({
@@ -2648,21 +2619,3 @@ class AutocompleteWithNativeAutocompleteAttribute {
26482619
})
26492620
class InputWithoutAutocompleteAndDisabled {
26502621
}
2651-
2652-
@Component({
2653-
template: `
2654-
<input type="number" matInput [matAutocomplete]="autoOne">
2655-
<mat-autocomplete #autoOne>
2656-
<mat-option [value]="0">First</mat-option>
2657-
</mat-autocomplete>
2658-
2659-
<mat-autocomplete #autoTow>
2660-
<mat-option [value]="1">Second</mat-option>
2661-
</mat-autocomplete>
2662-
`,
2663-
})
2664-
class DynamicallyChangingAutocomplete {
2665-
@ViewChild('autoOne') autoOne: MatAutocomplete;
2666-
@ViewChild('autoTow') autoTow: MatAutocomplete;
2667-
@ViewChild(MatAutocompleteTrigger) trigger: MatAutocompleteTrigger;
2668-
}

src/lib/autocomplete/autocomplete.ts

+1-12
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ import {
2424
TemplateRef,
2525
ViewChild,
2626
ViewEncapsulation,
27-
AfterViewInit,
28-
ViewContainerRef,
2927
} from '@angular/core';
3028
import {
3129
CanDisableRipple,
@@ -35,7 +33,6 @@ import {
3533
MatOption,
3634
mixinDisableRipple,
3735
} from '@angular/material/core';
38-
import {TemplatePortal} from '@angular/cdk/portal';
3936

4037

4138
/**
@@ -95,17 +92,14 @@ export function MAT_AUTOCOMPLETE_DEFAULT_OPTIONS_FACTORY(): MatAutocompleteDefau
9592
]
9693
})
9794
export class MatAutocomplete extends _MatAutocompleteMixinBase implements AfterContentInit,
98-
AfterViewInit, CanDisableRipple {
95+
CanDisableRipple {
9996

10097
/** Manages active item in option list based on key events. */
10198
_keyManager: ActiveDescendantKeyManager<MatOption>;
10299

103100
/** Whether the autocomplete panel should be visible, depending on option length. */
104101
showPanel: boolean = false;
105102

106-
/** @docs-private */
107-
_portal: TemplatePortal;
108-
109103
/** Whether the autocomplete panel is open. */
110104
get isOpen(): boolean { return this._isOpen && this.showPanel; }
111105
_isOpen: boolean = false;
@@ -171,17 +165,12 @@ export class MatAutocomplete extends _MatAutocompleteMixinBase implements AfterC
171165
constructor(
172166
private _changeDetectorRef: ChangeDetectorRef,
173167
private _elementRef: ElementRef<HTMLElement>,
174-
private _viewContainerRef: ViewContainerRef,
175168
@Inject(MAT_AUTOCOMPLETE_DEFAULT_OPTIONS) defaults: MatAutocompleteDefaultOptions) {
176169
super();
177170

178171
this._autoActiveFirstOption = !!defaults.autoActiveFirstOption;
179172
}
180173

181-
ngAfterViewInit() {
182-
this._portal = new TemplatePortal(this.template, this._viewContainerRef);
183-
}
184-
185174
ngAfterContentInit() {
186175
this._keyManager = new ActiveDescendantKeyManager<MatOption>(this.options).withWrap();
187176
// Set the initial visibility state.

0 commit comments

Comments
 (0)