mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-23 14:01:20 +08:00
Fix some angular (#16615)
* fix(angular): platform types fixes #16535 * fix(angular): memory leak in lifecycle events fixes #16285 * fix ci * single core
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
import { ApplicationRef, ComponentFactoryResolver, Injectable, InjectionToken, Injector, NgZone, ViewContainerRef } from '@angular/core';
|
||||
import { FrameworkDelegate, ViewLifecycle } from '@ionic/core';
|
||||
import { FrameworkDelegate } from '@ionic/core';
|
||||
import { NavParams } from '../directives/navigation/nav-params';
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@ export class AngularDelegate {
|
||||
export class AngularFrameworkDelegate implements FrameworkDelegate {
|
||||
|
||||
private elRefMap = new WeakMap<HTMLElement, any>();
|
||||
private elEventsMap = new WeakMap<HTMLElement, () => void>();
|
||||
|
||||
constructor(
|
||||
private resolver: ComponentFactoryResolver,
|
||||
@ -37,7 +38,8 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
|
||||
return new Promise(resolve => {
|
||||
this.zone.run(() => {
|
||||
const el = attachView(
|
||||
this.resolver, this.injector, this.location, this.appRef, this.elRefMap,
|
||||
this.resolver, this.injector, this.location, this.appRef,
|
||||
this.elRefMap, this.elEventsMap,
|
||||
container, component, params, cssClasses
|
||||
);
|
||||
resolve(el);
|
||||
@ -52,6 +54,11 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
|
||||
if (componentRef) {
|
||||
componentRef.destroy();
|
||||
this.elRefMap.delete(component);
|
||||
const unbindEvents = this.elEventsMap.get(component);
|
||||
if (unbindEvents) {
|
||||
unbindEvents();
|
||||
this.elEventsMap.delete(component);
|
||||
}
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
@ -65,6 +72,7 @@ export function attachView(
|
||||
location: ViewContainerRef | undefined,
|
||||
appRef: ApplicationRef,
|
||||
elRefMap: WeakMap<HTMLElement, any>,
|
||||
elEventsMap: WeakMap<HTMLElement, () => void>,
|
||||
container: any, component: any, params: any, cssClasses: string[] | undefined
|
||||
) {
|
||||
const factory = resolver.resolveComponentFactory(component);
|
||||
@ -86,34 +94,41 @@ export function attachView(
|
||||
hostElement.classList.add(clazz);
|
||||
}
|
||||
}
|
||||
bindLifecycleEvents(instance, hostElement);
|
||||
const unbindEvents = bindLifecycleEvents(instance, hostElement);
|
||||
container.appendChild(hostElement);
|
||||
|
||||
if (!location) {
|
||||
appRef.attachView(componentRef.hostView);
|
||||
}
|
||||
|
||||
componentRef.changeDetectorRef.reattach();
|
||||
elRefMap.set(hostElement, componentRef);
|
||||
elEventsMap.set(hostElement, unbindEvents);
|
||||
return hostElement;
|
||||
}
|
||||
|
||||
const LIFECYCLES = [
|
||||
ViewLifecycle.WillEnter,
|
||||
ViewLifecycle.DidEnter,
|
||||
ViewLifecycle.WillLeave,
|
||||
ViewLifecycle.DidLeave,
|
||||
ViewLifecycle.WillUnload
|
||||
'ionViewWillEnter',
|
||||
'ionViewDidEnter',
|
||||
'ionViewWillLeave',
|
||||
'ionViewDidLeave',
|
||||
'ionViewWillUnload'
|
||||
];
|
||||
|
||||
export function bindLifecycleEvents(instance: any, element: HTMLElement) {
|
||||
LIFECYCLES.forEach(eventName => {
|
||||
element.addEventListener(eventName, (ev: any) => {
|
||||
const unregisters = LIFECYCLES.map(eventName => {
|
||||
const handler = (ev: any) => {
|
||||
if (typeof instance[eventName] === 'function') {
|
||||
instance[eventName](ev.detail);
|
||||
}
|
||||
});
|
||||
};
|
||||
element.addEventListener(eventName, handler);
|
||||
return () => {
|
||||
element.removeEventListener(eventName, handler);
|
||||
};
|
||||
});
|
||||
return () => {
|
||||
unregisters.forEach(fn => fn());
|
||||
};
|
||||
}
|
||||
|
||||
const NavParamsToken = new InjectionToken<any>('NavParamsToken');
|
||||
|
Reference in New Issue
Block a user