mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(scrolling): viewport ruler resize event running inside the NgZone (#12909)
Fixes the `resize` and `orientationchange` events from the `ViewportRuler` being run inside the `NgZone`, even though the intention is that they shouldn't be. The issue comes from the fact that we call `merge` outside the `NgZone`, however the thing that causes the event to be bound is the subscription right after it. Fixes #12883.
This commit is contained in:
committed by
vivian-hu
parent
3e1cff0618
commit
707a7ee7a5
@@ -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();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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<Event>(fromEvent(window, 'resize'), fromEvent(window, 'orientationchange'));
|
||||
}) : observableOf();
|
||||
ngZone.runOutsideAngular(() => {
|
||||
this._change = _platform.isBrowser ?
|
||||
merge<Event>(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() {
|
||||
|
||||
Reference in New Issue
Block a user