mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
refactor(core): implement __ignore_ng_zone__ flag (#51339)
This flag allows message event listeners to prevent callbacks from executing within the NgZone if they contain a special `__ignore_ng_zone__` flag. This functionality is built with Angular DevTools in mind, where it prevents an infinite change detection loop in inspecting applications that have message event listeners: CD -> Inspected app emits componentTreeDirty event to DevTools -> DevTools emits event to get new component Tree from Inspected app -> Inspected app message event listener fires -> CD PR Close #51339
This commit is contained in:
committed by
Jessica Janiuk
parent
2d96dc27b7
commit
04bffaa41c
@@ -419,6 +419,10 @@ function forkInnerZoneWithAngularBehavior(zone: NgZonePrivate) {
|
||||
onInvokeTask:
|
||||
(delegate: ZoneDelegate, current: Zone, target: Zone, task: Task, applyThis: any,
|
||||
applyArgs: any): any => {
|
||||
if (shouldBeIgnoredByZone(applyArgs)) {
|
||||
return delegate.invokeTask(target, task, applyThis, applyArgs);
|
||||
}
|
||||
|
||||
try {
|
||||
onEnter(zone);
|
||||
return delegate.invokeTask(target, task, applyThis, applyArgs);
|
||||
@@ -585,3 +589,18 @@ export function isStableFactory() {
|
||||
});
|
||||
return merge(isCurrentlyStable, isStable.pipe(share()));
|
||||
}
|
||||
|
||||
function shouldBeIgnoredByZone(applyArgs: unknown): boolean {
|
||||
if (!Array.isArray(applyArgs)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We should only ever get 1 arg passed through to invokeTask.
|
||||
// Short circuit here incase that behavior changes.
|
||||
if (applyArgs.length !== 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prevent triggering change detection when the __ignore_ng_zone__ flag is detected.
|
||||
return applyArgs[0].data?.['__ignore_ng_zone__'] === true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user