fix(angular): add support for Angular 14 (#25403)

Resolves #25353
This commit is contained in:
Sean Perkins
2022-06-07 10:11:53 -04:00
committed by GitHub
parent 0b275af5ac
commit 122cdcc825
6 changed files with 114 additions and 21 deletions

View File

@@ -6,6 +6,7 @@ import {
Injectable,
InjectionToken,
Injector,
ComponentRef,
} from '@angular/core';
import {
FrameworkDelegate,
@@ -16,18 +17,20 @@ import {
LIFECYCLE_WILL_UNLOAD,
} from '@ionic/core';
import { EnvironmentInjector } from '../di/r3_injector';
import { NavParams } from '../directives/navigation/nav-params';
import { isComponentFactoryResolver } from '../util/util';
@Injectable()
export class AngularDelegate {
constructor(private zone: NgZone, private appRef: ApplicationRef) {}
create(
resolver: ComponentFactoryResolver,
resolverOrInjector: ComponentFactoryResolver,
injector: Injector,
location?: ViewContainerRef
): AngularFrameworkDelegate {
return new AngularFrameworkDelegate(resolver, injector, location, this.appRef, this.zone);
return new AngularFrameworkDelegate(resolverOrInjector, injector, location, this.appRef, this.zone);
}
}
@@ -36,7 +39,7 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
private elEventsMap = new WeakMap<HTMLElement, () => void>();
constructor(
private resolver: ComponentFactoryResolver,
private resolverOrInjector: ComponentFactoryResolver | EnvironmentInjector,
private injector: Injector,
private location: ViewContainerRef | undefined,
private appRef: ApplicationRef,
@@ -48,7 +51,7 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
return new Promise((resolve) => {
const el = attachView(
this.zone,
this.resolver,
this.resolverOrInjector,
this.injector,
this.location,
this.appRef,
@@ -85,7 +88,7 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
export const attachView = (
zone: NgZone,
resolver: ComponentFactoryResolver,
resolverOrInjector: ComponentFactoryResolver | EnvironmentInjector,
injector: Injector,
location: ViewContainerRef | undefined,
appRef: ApplicationRef,
@@ -96,14 +99,29 @@ export const attachView = (
params: any,
cssClasses: string[] | undefined
): any => {
const factory = resolver.resolveComponentFactory(component);
let componentRef: ComponentRef<any>;
const childInjector = Injector.create({
providers: getProviders(params),
parent: injector,
});
const componentRef = location
? location.createComponent(factory, location.length, childInjector)
: factory.create(childInjector);
if (resolverOrInjector && isComponentFactoryResolver(resolverOrInjector)) {
// Angular 13 and lower
const factory = resolverOrInjector.resolveComponentFactory(component);
componentRef = location
? location.createComponent(factory, location.length, childInjector)
: factory.create(childInjector);
} else if (location) {
// Angular 14
const environmentInjector = resolverOrInjector;
componentRef = location.createComponent(component, {
index: location.indexOf,
injector: childInjector,
environmentInjector,
} as any);
} else {
return null;
}
const instance = componentRef.instance;
const hostElement = componentRef.location.nativeElement;

View File

@@ -1,6 +1,7 @@
import { ComponentFactoryResolver, Injector, Injectable } from '@angular/core';
import { ComponentFactoryResolver, Injector, Injectable, Optional } from '@angular/core';
import { ModalOptions, modalController } from '@ionic/core';
import { EnvironmentInjector } from '../di/r3_injector';
import { OverlayBaseController } from '../util/overlay';
import { AngularDelegate } from './angular-delegate';
@@ -10,7 +11,9 @@ export class ModalController extends OverlayBaseController<ModalOptions, HTMLIon
constructor(
private angularDelegate: AngularDelegate,
private resolver: ComponentFactoryResolver,
private injector: Injector
private injector: Injector,
// TODO: FW-1641: Migrate to Angular's version once Angular 13 is dropped
@Optional() private environmentInjector: EnvironmentInjector
) {
super(modalController);
}
@@ -18,7 +21,7 @@ export class ModalController extends OverlayBaseController<ModalOptions, HTMLIon
create(opts: ModalOptions): Promise<HTMLIonModalElement> {
return super.create({
...opts,
delegate: this.angularDelegate.create(this.resolver, this.injector),
delegate: this.angularDelegate.create(this.resolver ?? this.environmentInjector, this.injector),
});
}
}

View File

@@ -1,6 +1,7 @@
import { ComponentFactoryResolver, Injector, Injectable } from '@angular/core';
import { ComponentFactoryResolver, Injector, Injectable, Optional } from '@angular/core';
import { PopoverOptions, popoverController } from '@ionic/core';
import { EnvironmentInjector } from '../di/r3_injector';
import { OverlayBaseController } from '../util/overlay';
import { AngularDelegate } from './angular-delegate';
@@ -10,7 +11,9 @@ export class PopoverController extends OverlayBaseController<PopoverOptions, HTM
constructor(
private angularDelegate: AngularDelegate,
private resolver: ComponentFactoryResolver,
private injector: Injector
private injector: Injector,
// TODO: FW-1641: Migrate to Angular's version once Angular 13 is dropped
@Optional() private environmentInjector: EnvironmentInjector
) {
super(popoverController);
}
@@ -18,7 +21,7 @@ export class PopoverController extends OverlayBaseController<PopoverOptions, HTM
create(opts: PopoverOptions): Promise<HTMLIonPopoverElement> {
return super.create({
...opts,
delegate: this.angularDelegate.create(this.resolver, this.injector),
delegate: this.angularDelegate.create(this.resolver ?? this.environmentInjector, this.injector),
});
}
}