Skip to content

Commit 144c429

Browse files
atscottcrisbeto
authored andcommitted
fix(upgrade): Make zoneless work with hybrid apps (#61660)
Hybrid applications trigger a digest when `onMicrotaskEmpty` emits so that the AngularJS app can run its lifecycle when the Angular app does. For ZoneJS applications, this is effectively after every render/app tick. This change updates the code to use `afterEveryRender` instead. fixes #61640 PR Close #61660
1 parent 8752014 commit 144c429

File tree

1 file changed

+32
-13
lines changed

1 file changed

+32
-13
lines changed

packages/upgrade/static/src/upgrade_module.ts

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,15 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import {Injector, NgModule, NgZone, PlatformRef, Testability} from '@angular/core';
9+
import {
10+
Injector,
11+
ApplicationRef,
12+
NgModule,
13+
NgZone,
14+
PlatformRef,
15+
Testability,
16+
ɵNoopNgZone,
17+
} from '@angular/core';
1018

1119
import {ɵangular1, ɵconstants, ɵutil} from '../common';
1220

@@ -145,6 +153,7 @@ export class UpgradeModule {
145153
public $injector: any /*angular.IInjectorService*/;
146154
/** The Angular Injector **/
147155
public injector: Injector;
156+
private readonly applicationRef: ApplicationRef;
148157

149158
constructor(
150159
/** The root `Injector` for the upgrade application. */
@@ -159,6 +168,7 @@ export class UpgradeModule {
159168
private platformRef: PlatformRef,
160169
) {
161170
this.injector = new NgAdapterInjector(injector);
171+
this.applicationRef = this.injector.get(ApplicationRef);
162172
}
163173

164174
/**
@@ -295,19 +305,28 @@ export class UpgradeModule {
295305
// Wire up the ng1 rootScope to run a digest cycle whenever the zone settles
296306
// We need to do this in the next tick so that we don't prevent the bootup stabilizing
297307
setTimeout(() => {
298-
const subscription = this.ngZone.onMicrotaskEmpty.subscribe(() => {
299-
if ($rootScope.$$phase) {
300-
if (typeof ngDevMode === 'undefined' || ngDevMode) {
301-
console.warn(
302-
'A digest was triggered while one was already in progress. This may mean that something is triggering digests outside the Angular zone.',
303-
);
304-
}
305-
306-
return $rootScope.$evalAsync();
307-
}
308+
const synchronize = () => {
309+
this.ngZone.run(() => {
310+
if ($rootScope.$$phase) {
311+
if (typeof ngDevMode === 'undefined' || ngDevMode) {
312+
console.warn(
313+
'A digest was triggered while one was already in progress. This may mean that something is triggering digests outside the Angular zone.',
314+
);
315+
}
308316

309-
return $rootScope.$digest();
310-
});
317+
$rootScope.$evalAsync();
318+
} else {
319+
$rootScope.$digest();
320+
}
321+
});
322+
};
323+
const subscription =
324+
// We _DO NOT_ usually want to have any code that does one thing for zoneless and another for ZoneJS.
325+
// This is only here because there is not enough coverage for hybrid apps anymore so we cannot
326+
// be confident that making UpgradeModule work with zoneless is a non-breaking change.
327+
this.ngZone instanceof ɵNoopNgZone
328+
? (this.applicationRef as any).afterTick.subscribe(() => synchronize())
329+
: this.ngZone.onMicrotaskEmpty.subscribe(() => synchronize());
311330
$rootScope.$on('$destroy', () => {
312331
subscription.unsubscribe();
313332
});

0 commit comments

Comments
 (0)