所以我创建了一个动态模态服务,用于在当前视图中呈现给定的组件。
模态服务:
import {
Injectable,
Component,
ComponentResolver,
ComponentMetadata,
ReflectiveInjector
} from '@angular/core';
import { ModalComponent } from './modal-cmp';
@Injectable()
export class ModalService {
viewContainerRef: any;
constructor(private resolver: ComponentResolver) { }
create(cmp) {
if(this.viewContainerRef) {
this.resolveComponent(cmp).then( factory => {
this.createShell(factory.selector, cmp).then( generated => {
this.viewContainerRef.createComponent(generated);
});
});
}
}
private resolveComponent(cmp) {
return this.resolver.resolveComponent(cmp);
}
private createShell(selector, cmp) {
const metadata = new ComponentMetadata({
selector: 'dynamic-tpl',
template: `
<app-modal>
<${selector}></${selector}>
</app-modal>
`,
directives: [ ModalComponent, cmp ]
});
const cmpClass = class DynamicTpl {};
const decorated = Component(metadata)(cmpClass);
return this.resolveComponent(decorated);
}
setViewContainerRef(vcr:any) {
this.viewContainerRef = vcr;
}
}
模态组件:
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
@Component({
moduleId: module.id,
selector: 'app-modal',
templateUrl: 'modal.component.html'
})
export class ModalComponent implements OnInit, AfterViewInit {
@ViewChild('modalRef') modalRef;
element: HTMLElement;
constructor() { }
ngOnInit() {
this.element = this.modalRef.nativeElement;
}
ngAfterViewInit() {
setTimeout(() => {
this.element.classList.add('entering');
})
}
public destroy() {
this.element.classList.remove('entering');
this.element.classList.add('leaving');
const transitionEnd = () => {
console.log('modal closed');
this.element.removeEventListener('transitionend', transitionEnd);
this.element.parentNode.removeChild(this.element);
}
this.element.addEventListener('transitionend', transitionEnd);
}
}
https://plnkr.co/edit/DuPU6uBgu0lcHtVrr5ir?p=preview
因此,我们的想法是拥有一个处理转换和定位的模态组件,而服务则处理动态创建。但是这个模型存在问题,或者至少是执行问题。我无法从其子组件访问ModalComponent方法,因此我无法从子组件中关闭模态(例如,在保存模态数据时)。问题如下:
如何改进模型? 如何从子组件访问Modals组件?