Skip to content

Commit e4cc453

Browse files
committed
fix(autocomplete): update template when changing autocomplete in trigger
1 parent 5d54920 commit e4cc453

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

src/lib/autocomplete/autocomplete-trigger.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,8 +569,15 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
569569
throw getMatAutocompleteMissingPanelError();
570570
}
571571

572-
if (!this._overlayRef) {
572+
if (!this._portal || this._portal.templateRef !== this.autocomplete.template) {
573573
this._portal = new TemplatePortal(this.autocomplete.template, this._viewContainerRef);
574+
575+
if (this._overlayRef && this._overlayRef.hasAttached()) {
576+
this._overlayRef.detach();
577+
}
578+
}
579+
580+
if (!this._overlayRef) {
574581
this._overlayRef = this._overlay.create(this._getOverlayConfig());
575582

576583
// Use the `keydownEvents` in order to take advantage of

src/lib/autocomplete/autocomplete.spec.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2221,6 +2221,38 @@ describe('MatAutocomplete', () => {
22212221
expect(formControl.value).toBe('Cal', 'Expected new value to be propagated to model');
22222222
}));
22232223

2224+
it('should work when dynamically changing the autocomplete', () => {
2225+
const fixture = createComponent(DynamicallyChangingAutocomplete);
2226+
fixture.detectChanges();
2227+
const input = fixture.debugElement.query(By.css('input')).nativeElement;
2228+
2229+
dispatchFakeEvent(input, 'focusin');
2230+
fixture.detectChanges();
2231+
2232+
expect(overlayContainerElement.textContent).toContain('First',
2233+
`Expected panel to display the option of the first autocomplete.`);
2234+
expect(overlayContainerElement.textContent).not.toContain('Second',
2235+
`Expected panel to not display the option of the second autocomplete.`);
2236+
2237+
// close overlay
2238+
dispatchFakeEvent(document, 'click');
2239+
fixture.detectChanges();
2240+
2241+
// Switch to second autocomplete
2242+
fixture.componentInstance.selected = 1;
2243+
fixture.detectChanges();
2244+
2245+
// reopen agian
2246+
dispatchFakeEvent(input, 'focusin');
2247+
fixture.detectChanges();
2248+
2249+
expect(overlayContainerElement.textContent).not.toContain('First',
2250+
`Expected panel to not display the option of the first autocomplete.`);
2251+
expect(overlayContainerElement.textContent).toContain('Second',
2252+
`Expected panel to display the option of the second autocomplete.`);
2253+
2254+
});
2255+
22242256
});
22252257

22262258
@Component({
@@ -2607,3 +2639,19 @@ class AutocompleteWithNativeAutocompleteAttribute {
26072639
})
26082640
class InputWithoutAutocompleteAndDisabled {
26092641
}
2642+
2643+
@Component({
2644+
template: `
2645+
<input type="number" matInput [matAutocomplete]="selected ? auto1 : auto0">
2646+
<mat-autocomplete #auto0="matAutocomplete">
2647+
<mat-option [value]="0">First</mat-option>
2648+
</mat-autocomplete>
2649+
2650+
<mat-autocomplete #auto1="matAutocomplete">
2651+
<mat-option [value]="1">Second</mat-option>
2652+
</mat-autocomplete>
2653+
`,
2654+
})
2655+
class DynamicallyChangingAutocomplete {
2656+
selected = 0;
2657+
}

0 commit comments

Comments
 (0)