Skip to content

fix(upgrade): Make zoneless work with hybrid apps #61660

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 35 additions & 13 deletions packages/upgrade/static/src/upgrade_module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,16 @@
* found in the LICENSE file at https://angular.dev/license
*/

import {Injector, NgModule, NgZone, PlatformRef, Testability} from '@angular/core';
import {
Injector,
ApplicationRef,
NgModule,
NgZone,
PlatformRef,
Testability,
afterEveryRender,
ɵNoopNgZone,
} from '@angular/core';

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

Expand Down Expand Up @@ -145,6 +154,7 @@ export class UpgradeModule {
public $injector: any /*angular.IInjectorService*/;
/** The Angular Injector **/
public injector: Injector;
private readonly applicationRef: ApplicationRef;

constructor(
/** The root `Injector` for the upgrade application. */
Expand All @@ -159,6 +169,7 @@ export class UpgradeModule {
private platformRef: PlatformRef,
) {
this.injector = new NgAdapterInjector(injector);
this.applicationRef = this.injector.get(ApplicationRef);
}

/**
Expand Down Expand Up @@ -295,19 +306,30 @@ export class UpgradeModule {
// Wire up the ng1 rootScope to run a digest cycle whenever the zone settles
// We need to do this in the next tick so that we don't prevent the bootup stabilizing
setTimeout(() => {
const subscription = this.ngZone.onMicrotaskEmpty.subscribe(() => {
if ($rootScope.$$phase) {
if (typeof ngDevMode === 'undefined' || ngDevMode) {
console.warn(
'A digest was triggered while one was already in progress. This may mean that something is triggering digests outside the Angular zone.',
);
}

return $rootScope.$evalAsync();
}
const synchronize = () => {
this.ngZone.run(() => {
if ($rootScope.$$phase) {
if (typeof ngDevMode === 'undefined' || ngDevMode) {
console.warn(
'A digest was triggered while one was already in progress. This may mean that something is triggering digests outside the Angular zone.',
);
}

return $rootScope.$digest();
});
$rootScope.$evalAsync();
} else {
$rootScope.$digest();
}
});
};
const subscription =
// We _DO NOT_ usually want to have any code that does one thing for zoneless and another for ZoneJS.
// This is only here because there is not enough coverage for hybrid apps anymore so we cannot
// be confident that making UpgradeModule work with zoneless is a non-breaking change.
this.ngZone instanceof ɵNoopNgZone
? // Ideally this could be afterEveryRender but `afterTick` is a closer approximation to `onMicrotaskEmpty`
// and makes a difference for at least 1 use-case internally (no deeper investigation was performed).
(this.applicationRef as any).afterTick.subscribe(() => synchronize())
: this.ngZone.onMicrotaskEmpty.subscribe(() => synchronize());
$rootScope.$on('$destroy', () => {
subscription.unsubscribe();
});
Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy