fix(angular): viewContainer in overlays

This commit is contained in:
Manu Mtz.-Almeida
2018-04-13 15:01:04 +02:00
parent db5313e45b
commit 8ad3df9736
3 changed files with 23 additions and 14 deletions

View File

@ -1,4 +1,4 @@
import { ComponentFactoryResolver, Injectable, InjectionToken, Injector, NgZone, ViewContainerRef } from '@angular/core'; import { ApplicationRef, ComponentFactoryResolver, Injectable, InjectionToken, Injector, NgZone, ViewContainerRef } from '@angular/core';
import { FrameworkDelegate, ViewLifecycle } from '@ionic/core'; import { FrameworkDelegate, ViewLifecycle } from '@ionic/core';
import { NavParams } from '../directives/navigation/nav-params'; import { NavParams } from '../directives/navigation/nav-params';
@ -7,15 +7,16 @@ import { NavParams } from '../directives/navigation/nav-params';
export class AngularDelegate { export class AngularDelegate {
constructor( constructor(
private zone: NgZone private zone: NgZone,
private appRef: ApplicationRef
) {} ) {}
create( create(
resolver: ComponentFactoryResolver, resolver: ComponentFactoryResolver,
injector: Injector, injector: Injector,
location: ViewContainerRef, location?: ViewContainerRef,
) { ) {
return new AngularFrameworkDelegate(resolver, injector, location, this.zone); return new AngularFrameworkDelegate(resolver, injector, location, this.appRef, this.zone);
} }
} }
@ -28,6 +29,7 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
private resolver: ComponentFactoryResolver, private resolver: ComponentFactoryResolver,
private injector: Injector, private injector: Injector,
private location: ViewContainerRef, private location: ViewContainerRef,
private appRef: ApplicationRef,
private zone: NgZone, private zone: NgZone,
) {} ) {}
@ -35,7 +37,7 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
return new Promise(resolve => { return new Promise(resolve => {
this.zone.run(() => { this.zone.run(() => {
const el = attachView( const el = attachView(
this.resolver, this.injector, this.location, this.elRefMap, this.resolver, this.injector, this.location, this.appRef, this.elRefMap,
container, component, params, cssClasses container, component, params, cssClasses
); );
resolve(el); resolve(el);
@ -60,12 +62,17 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
export function attachView( export function attachView(
resolver: ComponentFactoryResolver, resolver: ComponentFactoryResolver,
injector: Injector, injector: Injector,
location: ViewContainerRef, location: ViewContainerRef|undefined,
appRef: ApplicationRef,
elRefMap: WeakMap<HTMLElement, any>, elRefMap: WeakMap<HTMLElement, any>,
container: any, component: any, params?: any, cssClasses?: string[]) { container: any, component: any, params: any, cssClasses: string[]
) {
const factory = resolver.resolveComponentFactory(component); const factory = resolver.resolveComponentFactory(component);
const childInjector = Injector.create(getProviders(params), injector); const childInjector = Injector.create(getProviders(params), injector);
const componentRef = location.createComponent(factory, location.length, childInjector); const componentRef = (location)
? location.createComponent(factory, location.length, childInjector)
: factory.create(childInjector);
const hostElement = componentRef.location.nativeElement; const hostElement = componentRef.location.nativeElement;
if (params) { if (params) {
Object.assign(hostElement, params); Object.assign(hostElement, params);
@ -76,6 +83,10 @@ export function attachView(
bindLifecycleEvents(componentRef.instance, hostElement); bindLifecycleEvents(componentRef.instance, hostElement);
container.appendChild(hostElement); container.appendChild(hostElement);
if (!location) {
appRef.attachView(componentRef.hostView);
}
componentRef.changeDetectorRef.reattach(); componentRef.changeDetectorRef.reattach();
elRefMap.set(hostElement, componentRef); elRefMap.set(hostElement, componentRef);
return hostElement; return hostElement;

View File

@ -1,4 +1,4 @@
import { ComponentFactoryResolver, Injectable, Injector, ViewContainerRef } from '@angular/core'; import { ComponentFactoryResolver, Injectable, Injector } from '@angular/core';
import { ModalOptions } from '@ionic/core'; import { ModalOptions } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay'; import { OverlayBaseController } from '../util/overlay';
import { AngularDelegate } from './angular-delegate'; import { AngularDelegate } from './angular-delegate';
@ -10,7 +10,6 @@ export class ModalController extends OverlayBaseController<ModalOptions, HTMLIon
private angularDelegate: AngularDelegate, private angularDelegate: AngularDelegate,
private resolver: ComponentFactoryResolver, private resolver: ComponentFactoryResolver,
private injector: Injector, private injector: Injector,
private location: ViewContainerRef,
) { ) {
super('ion-modal-controller'); super('ion-modal-controller');
} }
@ -18,7 +17,7 @@ export class ModalController extends OverlayBaseController<ModalOptions, HTMLIon
create(opts?: ModalOptions): Promise<HTMLIonModalElement> { create(opts?: ModalOptions): Promise<HTMLIonModalElement> {
return super.create({ return super.create({
...opts, ...opts,
delegate: this.angularDelegate.create(this.resolver, this.injector, this.location) delegate: this.angularDelegate.create(this.resolver, this.injector)
}); });
} }
} }

View File

@ -1,4 +1,4 @@
import { ComponentFactoryResolver, Injectable, Injector, ViewContainerRef } from '@angular/core'; import { ComponentFactoryResolver, Injectable, Injector } from '@angular/core';
import { PopoverOptions } from '@ionic/core'; import { PopoverOptions } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay'; import { OverlayBaseController } from '../util/overlay';
import { AngularDelegate } from './angular-delegate'; import { AngularDelegate } from './angular-delegate';
@ -10,7 +10,6 @@ export class PopoverController extends OverlayBaseController<PopoverOptions, HTM
private angularDelegate: AngularDelegate, private angularDelegate: AngularDelegate,
private resolver: ComponentFactoryResolver, private resolver: ComponentFactoryResolver,
private injector: Injector, private injector: Injector,
private location: ViewContainerRef,
) { ) {
super('ion-popover-controller'); super('ion-popover-controller');
} }
@ -18,7 +17,7 @@ export class PopoverController extends OverlayBaseController<PopoverOptions, HTM
create(opts?: PopoverOptions): Promise<HTMLIonPopoverElement> { create(opts?: PopoverOptions): Promise<HTMLIonPopoverElement> {
return super.create({ return super.create({
...opts, ...opts,
delegate: this.angularDelegate.create(this.resolver, this.injector, this.location) delegate: this.angularDelegate.create(this.resolver, this.injector)
}); });
} }
} }