Skip to content

Commit ff01196

Browse files
authored
fix(material/autocomplete): re-enter the Angular zone when the NgZone.onStable emits (#24569)
The `NgZone.onStable` always emits outside of the Angular zone, but the zone has not been re-entered. This leads to change detection being called outside of the Angular zone and the `autocomplete.opened` also was emitting values outside of the Angular zone.
1 parent 0638419 commit ff01196

File tree

1 file changed

+20
-15
lines changed

1 file changed

+20
-15
lines changed

src/material/autocomplete/autocomplete-trigger.ts

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -526,22 +526,27 @@ export abstract class _MatAutocompleteTriggerBase
526526
// create a new stream of panelClosingActions, replacing any previous streams
527527
// that were created, and flatten it so our stream only emits closing events...
528528
switchMap(() => {
529-
const wasOpen = this.panelOpen;
530-
this._resetActiveItem();
531-
this.autocomplete._setVisibility();
532-
this._changeDetectorRef.detectChanges();
533-
534-
if (this.panelOpen) {
535-
this._overlayRef!.updatePosition();
536-
537-
// If the `panelOpen` state changed, we need to make sure to emit the `opened`
538-
// event, because we may not have emitted it when the panel was attached. This
539-
// can happen if the users opens the panel and there are no options, but the
540-
// options come in slightly later or as a result of the value changing.
541-
if (wasOpen !== this.panelOpen) {
542-
this.autocomplete.opened.emit();
529+
// The `NgZone.onStable` always emits outside of the Angular zone, thus we have to re-enter
530+
// the Angular zone. This will lead to change detection being called outside of the Angular
531+
// zone and the `autocomplete.opened` will also emit outside of the Angular.
532+
this._zone.run(() => {
533+
const wasOpen = this.panelOpen;
534+
this._resetActiveItem();
535+
this.autocomplete._setVisibility();
536+
this._changeDetectorRef.detectChanges();
537+
538+
if (this.panelOpen) {
539+
this._overlayRef!.updatePosition();
540+
541+
// If the `panelOpen` state changed, we need to make sure to emit the `opened`
542+
// event, because we may not have emitted it when the panel was attached. This
543+
// can happen if the users opens the panel and there are no options, but the
544+
// options come in slightly later or as a result of the value changing.
545+
if (wasOpen !== this.panelOpen) {
546+
this.autocomplete.opened.emit();
547+
}
543548
}
544-
}
549+
});
545550

546551
return this.panelClosingActions;
547552
}),

0 commit comments

Comments
 (0)