diff --git a/src/cdk/scrolling/viewport-ruler.spec.ts b/src/cdk/scrolling/viewport-ruler.spec.ts index 5877c4df8e6..f80fa25ee08 100644 --- a/src/cdk/scrolling/viewport-ruler.spec.ts +++ b/src/cdk/scrolling/viewport-ruler.spec.ts @@ -2,7 +2,7 @@ import {TestBed, inject, fakeAsync, tick} from '@angular/core/testing'; import {ScrollingModule} from './public-api'; import {ViewportRuler} from './viewport-ruler'; import {dispatchFakeEvent} from '@angular/cdk/testing'; - +import {NgZone} from '@angular/core'; // For all tests, we assume the browser window is 1024x786 (outerWidth x outerHeight). // The karma config has been set to this for local tests, and it is the default size @@ -140,5 +140,15 @@ describe('ViewportRuler', () => { expect(spy).toHaveBeenCalledTimes(1); subscription.unsubscribe(); })); + + it('should run the resize event outside the NgZone', () => { + const spy = jasmine.createSpy('viewport changed spy'); + const subscription = ruler.change(0).subscribe(() => spy(NgZone.isInAngularZone())); + + dispatchFakeEvent(window, 'resize'); + expect(spy).toHaveBeenCalledWith(false); + subscription.unsubscribe(); + }); + }); }); diff --git a/src/cdk/scrolling/viewport-ruler.ts b/src/cdk/scrolling/viewport-ruler.ts index 4035f0948ce..a94822d531f 100644 --- a/src/cdk/scrolling/viewport-ruler.ts +++ b/src/cdk/scrolling/viewport-ruler.ts @@ -36,11 +36,15 @@ export class ViewportRuler implements OnDestroy { private _invalidateCache: Subscription; constructor(private _platform: Platform, ngZone: NgZone) { - this._change = _platform.isBrowser ? ngZone.runOutsideAngular(() => { - return merge(fromEvent(window, 'resize'), fromEvent(window, 'orientationchange')); - }) : observableOf(); + ngZone.runOutsideAngular(() => { + this._change = _platform.isBrowser ? + merge(fromEvent(window, 'resize'), fromEvent(window, 'orientationchange')) : + observableOf(); - this._invalidateCache = this.change().subscribe(() => this._updateViewportSize()); + // Note that we need to do the subscription inside `runOutsideAngular` + // since subscribing is what causes the event listener to be added. + this._invalidateCache = this.change().subscribe(() => this._updateViewportSize()); + }); } ngOnDestroy() {