diff --git a/src/cdk/overlay/overlay-directives.spec.ts b/src/cdk/overlay/overlay-directives.spec.ts index eb086ace797e..0aea4c46403d 100644 --- a/src/cdk/overlay/overlay-directives.spec.ts +++ b/src/cdk/overlay/overlay-directives.spec.ts @@ -1,4 +1,4 @@ -import {Component, ElementRef, ViewChild} from '@angular/core'; +import {Component, ElementRef, NgZone, ViewChild} from '@angular/core'; import {By} from '@angular/platform-browser'; import { ComponentFixture, @@ -618,6 +618,18 @@ describe('Overlay directives', () => { .toBe(true); }); + it('should emit the position change handler inside the zone', () => { + let callsInZone: boolean[] = []; + + fixture.componentInstance.positionChangeHandler.and.callFake(() => { + callsInZone.push(NgZone.isInAngularZone()); + }); + fixture.componentInstance.isOpen = true; + fixture.detectChanges(); + + expect(callsInZone).toEqual([true]); + }); + it('should emit when attached', () => { expect(fixture.componentInstance.attachHandler).not.toHaveBeenCalled(); fixture.componentInstance.isOpen = true; diff --git a/src/cdk/overlay/overlay-directives.ts b/src/cdk/overlay/overlay-directives.ts index 4b560a2baff9..4775bfe6f7c3 100644 --- a/src/cdk/overlay/overlay-directives.ts +++ b/src/cdk/overlay/overlay-directives.ts @@ -16,6 +16,7 @@ import { Inject, InjectionToken, Input, + NgZone, OnChanges, OnDestroy, Optional, @@ -116,6 +117,7 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges { private _position: FlexibleConnectedPositionStrategy; private _scrollStrategyFactory: () => ScrollStrategy; private _disposeOnNavigation = false; + private _ngZone = inject(NgZone); /** Origin for the connected overlay. */ @Input('cdkConnectedOverlayOrigin') @@ -421,7 +423,7 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges { this._positionSubscription = this._position.positionChanges .pipe(takeWhile(() => this.positionChange.observers.length > 0)) .subscribe(position => { - this.positionChange.emit(position); + this._ngZone.run(() => this.positionChange.emit(position)); if (this.positionChange.observers.length === 0) { this._positionSubscription.unsubscribe();