mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(core): run afterRender callbacks outside of the Angular zone (#51551)
afterRender should run outside of the Angular zone so that it does not trigger further CD cycles PR Close #51551
This commit is contained in:
committed by
Jessica Janiuk
parent
a06140a2ca
commit
0c7c852ee7
@@ -10,6 +10,7 @@ import {assertInInjectionContext, Injector, ɵɵdefineInjectable} from '../di';
|
||||
import {inject} from '../di/injector_compatibility';
|
||||
import {RuntimeError, RuntimeErrorCode} from '../errors';
|
||||
import {DestroyRef} from '../linker/destroy_ref';
|
||||
import {NgZone} from '../zone';
|
||||
|
||||
import {isPlatformBrowser} from './util/misc_utils';
|
||||
|
||||
@@ -91,7 +92,8 @@ export function afterRender(callback: VoidFunction, options?: AfterRenderOptions
|
||||
let destroy: VoidFunction|undefined;
|
||||
const unregisterFn = injector.get(DestroyRef).onDestroy(() => destroy?.());
|
||||
const manager = injector.get(AfterRenderEventManager);
|
||||
const instance = new AfterRenderCallback(callback);
|
||||
const ngZone = injector.get(NgZone);
|
||||
const instance = new AfterRenderCallback(() => ngZone.runOutsideAngular(callback));
|
||||
|
||||
destroy = () => {
|
||||
manager.unregister(instance);
|
||||
@@ -155,9 +157,10 @@ export function afterNextRender(
|
||||
let destroy: VoidFunction|undefined;
|
||||
const unregisterFn = injector.get(DestroyRef).onDestroy(() => destroy?.());
|
||||
const manager = injector.get(AfterRenderEventManager);
|
||||
const ngZone = injector.get(NgZone);
|
||||
const instance = new AfterRenderCallback(() => {
|
||||
destroy?.();
|
||||
callback();
|
||||
ngZone.runOutsideAngular(callback);
|
||||
});
|
||||
|
||||
destroy = () => {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {PLATFORM_BROWSER_ID, PLATFORM_SERVER_ID} from '@angular/common/src/platform_id';
|
||||
import {afterNextRender, afterRender, AfterRenderRef, ChangeDetectorRef, Component, inject, Injector, PLATFORM_ID, ViewContainerRef} from '@angular/core';
|
||||
import {afterNextRender, afterRender, AfterRenderRef, ChangeDetectorRef, Component, inject, Injector, NgZone, PLATFORM_ID, ViewContainerRef} from '@angular/core';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
|
||||
describe('after render hooks', () => {
|
||||
@@ -225,6 +225,29 @@ describe('after render hooks', () => {
|
||||
expect(outerHookCount).toBe(3);
|
||||
expect(innerHookCount).toBe(2);
|
||||
});
|
||||
|
||||
it('should run outside of the Angular zone', () => {
|
||||
const zoneLog: boolean[] = [];
|
||||
|
||||
@Component({selector: 'comp'})
|
||||
class Comp {
|
||||
constructor() {
|
||||
afterRender(() => {
|
||||
zoneLog.push(NgZone.isInAngularZone());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [Comp],
|
||||
...COMMON_CONFIGURATION,
|
||||
});
|
||||
const fixture = TestBed.createComponent(Comp);
|
||||
|
||||
expect(zoneLog).toEqual([]);
|
||||
fixture.detectChanges();
|
||||
expect(zoneLog).toEqual([false]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('afterNextRender', () => {
|
||||
@@ -431,6 +454,29 @@ describe('after render hooks', () => {
|
||||
expect(outerHookCount).toBe(1);
|
||||
expect(innerHookCount).toBe(1);
|
||||
});
|
||||
|
||||
it('should run outside of the Angular zone', () => {
|
||||
const zoneLog: boolean[] = [];
|
||||
|
||||
@Component({selector: 'comp'})
|
||||
class Comp {
|
||||
constructor() {
|
||||
afterNextRender(() => {
|
||||
zoneLog.push(NgZone.isInAngularZone());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [Comp],
|
||||
...COMMON_CONFIGURATION,
|
||||
});
|
||||
const fixture = TestBed.createComponent(Comp);
|
||||
|
||||
expect(zoneLog).toEqual([]);
|
||||
fixture.detectChanges();
|
||||
expect(zoneLog).toEqual([false]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1980,7 +1980,7 @@
|
||||
"name": "tap"
|
||||
},
|
||||
{
|
||||
"name": "throwError5"
|
||||
"name": "throwError2"
|
||||
},
|
||||
{
|
||||
"name": "throwIfEmpty"
|
||||
|
||||
Reference in New Issue
Block a user