将子组件添加到父组件并将父组件添加到文档
Add child component to parent component and add parent to document
在 Angular 7 模态服务中,我正在创建一个模态 Stackblitz。
模态只是 DIV 添加到文档中,如下所示:
const modal = document.createElement('div');
modal.classList.add('modal');
modal.appendChild(this.element);
document.body.appendChild(this.modal);
modal
内容 (this.element) 是一个动态创建的组件。
我想要的是modal
也是一个动态添加的组件:
- 从 ModalComponent 创建模态(我认为类似于 2);
- 创建元素组件(完成);
- 将元素组件添加为模态组件的子组件;
- 向文档添加模态组件。
有人可以帮我解决 (3) 和 (4) 吗?不知道该怎么做。
模态
export class Modal {
protected modal: any = null;
close() {
this.modal.close();
}
}
模态服务
import { ApplicationRef, ComponentFactoryResolver, EmbeddedViewRef, Injectable, Injector, ComponentRef, ReflectiveInjector } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ModalService {
private component: ComponentRef<any>;
private element: any;
private stage: any;
constructor(private componentFactoryResolver: ComponentFactoryResolver, private application: ApplicationRef, private injector: Injector) { }
open(component: any, data: any): void {
if(this.element)
return;
const injector: Injector = ReflectiveInjector.resolveAndCreate([{ provide: 'modal', useValue: data }]);
this.component = this.componentFactoryResolver.resolveComponentFactory(component).create(injector);
this.component.instance.modal = this;
this.application.attachView(this.component.hostView);
this.element = (this.component.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
const modal = document.createElement('div');
modal.classList.add('modal');
modal.appendChild(this.element);
document.body.appendChild(this.modal);
}
close(): void {
this.application.detachView(this.component.hostView);
this.stage.parentNode.removeChild(this.stage);
this.component.destroy();
this.element = null;
}
}
首先您需要动态创建该内部组件,然后在 ComponentFactory.create
方法中使用 projectableNodes
参数将其投影到您动态创建的 ModalComponent
.
ModalComponent 应该在其模板中包含 ng-content 标签:
<div class="stage">
<div class="modal">
<ng-content></ng-content>
</div>
</div>
modal.service.ts
open(component: Type<Modal>): void {
if (this.modalRef)
return;
this.elementRef = this.componentFactoryResolver
.resolveComponentFactory(component)
.create(this.injector);
this.appRef.attachView(this.elementRef.hostView);
this.elementRef.instance.modal = this;
this.modalRef = this.componentFactoryResolver
.resolveComponentFactory(ModalComponent)
.create(this.injector, [[this.elementRef.location.nativeElement]]);
\/
here we're projecting inner component into modal
this.appRef.attachView(this.modalRef.hostView);
document.body.appendChild(this.modalRef.location.nativeElement);
}
close(): void {
this.appRef.detachView(this.elementRef.hostView);
this.elementRef.destroy();
this.elementRef = null;
this.appRef.detachView(this.modalRef.hostView);
this.modalRef.destroy();
this.modalRef = null;
}
在 Angular 7 模态服务中,我正在创建一个模态 Stackblitz。
模态只是 DIV 添加到文档中,如下所示:
const modal = document.createElement('div');
modal.classList.add('modal');
modal.appendChild(this.element);
document.body.appendChild(this.modal);
modal
内容 (this.element) 是一个动态创建的组件。
我想要的是modal
也是一个动态添加的组件:
- 从 ModalComponent 创建模态(我认为类似于 2);
- 创建元素组件(完成);
- 将元素组件添加为模态组件的子组件;
- 向文档添加模态组件。
有人可以帮我解决 (3) 和 (4) 吗?不知道该怎么做。
模态
export class Modal {
protected modal: any = null;
close() {
this.modal.close();
}
}
模态服务
import { ApplicationRef, ComponentFactoryResolver, EmbeddedViewRef, Injectable, Injector, ComponentRef, ReflectiveInjector } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ModalService {
private component: ComponentRef<any>;
private element: any;
private stage: any;
constructor(private componentFactoryResolver: ComponentFactoryResolver, private application: ApplicationRef, private injector: Injector) { }
open(component: any, data: any): void {
if(this.element)
return;
const injector: Injector = ReflectiveInjector.resolveAndCreate([{ provide: 'modal', useValue: data }]);
this.component = this.componentFactoryResolver.resolveComponentFactory(component).create(injector);
this.component.instance.modal = this;
this.application.attachView(this.component.hostView);
this.element = (this.component.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
const modal = document.createElement('div');
modal.classList.add('modal');
modal.appendChild(this.element);
document.body.appendChild(this.modal);
}
close(): void {
this.application.detachView(this.component.hostView);
this.stage.parentNode.removeChild(this.stage);
this.component.destroy();
this.element = null;
}
}
首先您需要动态创建该内部组件,然后在 ComponentFactory.create
方法中使用 projectableNodes
参数将其投影到您动态创建的 ModalComponent
.
ModalComponent 应该在其模板中包含 ng-content 标签:
<div class="stage">
<div class="modal">
<ng-content></ng-content>
</div>
</div>
modal.service.ts
open(component: Type<Modal>): void {
if (this.modalRef)
return;
this.elementRef = this.componentFactoryResolver
.resolveComponentFactory(component)
.create(this.injector);
this.appRef.attachView(this.elementRef.hostView);
this.elementRef.instance.modal = this;
this.modalRef = this.componentFactoryResolver
.resolveComponentFactory(ModalComponent)
.create(this.injector, [[this.elementRef.location.nativeElement]]);
\/
here we're projecting inner component into modal
this.appRef.attachView(this.modalRef.hostView);
document.body.appendChild(this.modalRef.location.nativeElement);
}
close(): void {
this.appRef.detachView(this.elementRef.hostView);
this.elementRef.destroy();
this.elementRef = null;
this.appRef.detachView(this.modalRef.hostView);
this.modalRef.destroy();
this.modalRef = null;
}