refactor(angular): optionally wrap the user's template in

This commit is contained in:
Dan Bucholtz
2018-01-03 16:23:16 -06:00
parent 6ab623272c
commit 3604adf841
4 changed files with 31 additions and 18 deletions

View File

@ -22,11 +22,12 @@ export class IonNavDelegate implements FrameworkDelegate {
attachViewToDom(elementOrContainerToMountTo: HTMLIonNavElement, elementOrComponentToMount: Type<any>, _propsOrDataObj?: any, classesToAdd?: string[]): Promise<AngularMountingData> { attachViewToDom(elementOrContainerToMountTo: HTMLIonNavElement, elementOrComponentToMount: Type<any>, _propsOrDataObj?: any, classesToAdd?: string[]): Promise<AngularMountingData> {
return this.angularComponentMounter.attachViewToDom(elementOrContainerToMountTo, null, elementOrComponentToMount, this.componentResolveFactory, this.injector, _propsOrDataObj, classesToAdd); // wrap whatever the user provides in an ion-page
return this.angularComponentMounter.attachViewToDom(elementOrContainerToMountTo, null, elementOrComponentToMount, this.componentResolveFactory, this.injector, _propsOrDataObj, classesToAdd, true);
} }
removeViewFromDom(_parentElement: HTMLElement, childElement: HTMLElement) { removeViewFromDom(parentElement: HTMLElement, childElement: HTMLElement) {
return this.angularComponentMounter.removeViewFromDom(childElement); return this.angularComponentMounter.removeViewFromDom(parentElement, childElement);
} }
} }

View File

@ -20,45 +20,57 @@ export class AngularComponentMounter {
constructor(private defaultCfr: ComponentFactoryResolver, private zone: NgZone, private appRef: ApplicationRef) { constructor(private defaultCfr: ComponentFactoryResolver, private zone: NgZone, private appRef: ApplicationRef) {
} }
attachViewToDom(parentElement: HTMLElement, hostElement: HTMLElement, componentToMount: Type<any>, componentResolveFactory: ComponentFactoryResolver, injector: Injector, data: any, classesToAdd: string[]): Promise<AngularMountingData> { attachViewToDom(parentElement: HTMLElement, hostElement: HTMLElement, componentToMount: Type<any>, componentResolveFactory: ComponentFactoryResolver, injector: Injector, data: any, classesToAdd: string[], wrapUserTemplateInIonPage: boolean): Promise<AngularMountingData> {
return new Promise((resolve) => { return new Promise((resolve) => {
this.zone.run(() => { this.zone.run(() => {
const crf = componentResolveFactory ? componentResolveFactory : this.defaultCfr; const crf = componentResolveFactory ? componentResolveFactory : this.defaultCfr;
const mountingData = attachViewToDom(crf, parentElement, hostElement, componentToMount, injector, this.appRef, data, classesToAdd); const mountingData = attachViewToDom(crf, parentElement, hostElement, componentToMount, injector, this.appRef, data, classesToAdd, wrapUserTemplateInIonPage);
resolve(mountingData); resolve(mountingData);
}); });
}); });
} }
removeViewFromDom(childElement: HTMLElement): Promise<any> { removeViewFromDom(parentElement: HTMLElement, childElement: HTMLElement): Promise<any> {
return new Promise((resolve) => { return new Promise((resolve) => {
this.zone.run(() => { this.zone.run(() => {
removeViewFromDom(childElement); removeViewFromDom(parentElement, childElement);
resolve(); resolve();
}); });
}); });
} }
} }
export function removeViewFromDom(childElement: HTMLElement) { export function removeViewFromDom(parentElement: HTMLElement, childElement: HTMLElement) {
const componentRef = elementToComponentRefMap.get(childElement); const componentRef = elementToComponentRefMap.get(childElement);
if (componentRef) { if (componentRef) {
componentRef.destroy(); componentRef.destroy();
if (parentElement.contains(childElement)) {
parentElement.removeChild(childElement);
}
} }
} }
export function attachViewToDom(crf: ComponentFactoryResolver, parentElement: HTMLElement, hostElement: HTMLElement, componentToMount: Type<any>, injector: Injector, appRef: ApplicationRef, data: any, classesToAdd: string[]): AngularMountingData { export function attachViewToDom(crf: ComponentFactoryResolver, parentElement: HTMLElement, hostElement: HTMLElement, componentToMount: Type<any>, injector: Injector, appRef: ApplicationRef, data: any, classesToAdd: string[], wrapUserTemplateInIonPage: boolean): AngularMountingData {
const componentProviders = ReflectiveInjector.resolve(getProviders(parentElement, data)); const componentProviders = ReflectiveInjector.resolve(getProviders(parentElement, data));
const componentFactory = crf.resolveComponentFactory(componentToMount); const componentFactory = crf.resolveComponentFactory(componentToMount);
if (!hostElement) { if (!hostElement) {
hostElement = document.createElement(componentFactory.selector); hostElement = document.createElement(componentFactory.selector);
} }
let mountingElement = hostElement;
if (wrapUserTemplateInIonPage) {
const ionPageElement = document.createElement('ion-page');
hostElement.appendChild(ionPageElement);
mountingElement = ionPageElement;
}
const childInjector = ReflectiveInjector.fromResolvedProviders(componentProviders, injector); const childInjector = ReflectiveInjector.fromResolvedProviders(componentProviders, injector);
const componentRef = componentFactory.create(childInjector, [], hostElement); const componentRef = componentFactory.create(childInjector, [], mountingElement);
for (const clazz of classesToAdd) { for (const clazz of classesToAdd) {
hostElement.classList.add(clazz); hostElement.classList.add(clazz);
} }
@ -71,8 +83,8 @@ export function attachViewToDom(crf: ComponentFactoryResolver, parentElement: HT
return { return {
componentFactory, componentFactory,
childInjector: childInjector, childInjector,
componentRef: componentRef, componentRef,
instance: componentRef.instance, instance: componentRef.instance,
angularHostElement: componentRef.location.nativeElement, angularHostElement: componentRef.location.nativeElement,
element: hostElement, element: hostElement,

View File

@ -31,11 +31,11 @@ export class ModalController implements FrameworkDelegate {
attachViewToDom(elementOrContainerToMountTo: HTMLElement, elementOrComponentToMount: Type<any>, _propsOrDataObj?: any, classesToAdd?: string[]): Promise<AngularMountingData> { attachViewToDom(elementOrContainerToMountTo: HTMLElement, elementOrComponentToMount: Type<any>, _propsOrDataObj?: any, classesToAdd?: string[]): Promise<AngularMountingData> {
return this.angularComponentMounter.attachViewToDom(elementOrContainerToMountTo, null, elementOrComponentToMount, this.componentResolveFactory, this.injector, _propsOrDataObj, classesToAdd); return this.angularComponentMounter.attachViewToDom(elementOrContainerToMountTo, null, elementOrComponentToMount, this.componentResolveFactory, this.injector, _propsOrDataObj, classesToAdd, true);
} }
removeViewFromDom(_parentElement: HTMLElement, childElement: HTMLElement) { removeViewFromDom(parentElement: HTMLElement, childElement: HTMLElement) {
return this.angularComponentMounter.removeViewFromDom(childElement); return this.angularComponentMounter.removeViewFromDom(parentElement, childElement);
} }
} }

View File

@ -31,11 +31,11 @@ export class PopoverController implements FrameworkDelegate {
attachViewToDom(elementOrContainerToMountTo: HTMLElement, elementOrComponentToMount: Type<any>, _propsOrDataObj?: any, classesToAdd?: string[]): Promise<AngularMountingData> { attachViewToDom(elementOrContainerToMountTo: HTMLElement, elementOrComponentToMount: Type<any>, _propsOrDataObj?: any, classesToAdd?: string[]): Promise<AngularMountingData> {
return this.angularComponentMounter.attachViewToDom(elementOrContainerToMountTo, null, elementOrComponentToMount, this.componentResolveFactory, this.injector, _propsOrDataObj, classesToAdd); return this.angularComponentMounter.attachViewToDom(elementOrContainerToMountTo, null, elementOrComponentToMount, this.componentResolveFactory, this.injector, _propsOrDataObj, classesToAdd, false);
} }
removeViewFromDom(_parentElement: HTMLElement, childElement: HTMLElement) { removeViewFromDom(parentElement: HTMLElement, childElement: HTMLElement) {
return this.angularComponentMounter.removeViewFromDom(childElement); return this.angularComponentMounter.removeViewFromDom(parentElement, childElement);
} }
} }