在某些情况下,我想让我的Angular Application重构。
我有一个html,单击不同按钮时,我想打开对话框,除了单击按钮时打开的组件外,其他方面都相同。
<button mat-raised-button (click)="openDialog('ComponentA')">Component A</button>
<button mat-raised-button (click)="openDialog('ComponentB')">Component B</button>
<button mat-raised-button (click)="openDialog('ComponentC')">Component C</button>
<button mat-raised-button (click)="openDialog('ComponentD')">Component D</button>
单击按钮后,我将调用openDialog,后者又将打开Dialog Box,其结构取决于通过的组件。
openDialog(component){
const dialogRef = this.dialog.open(component, {
width: '250px',
data: {name: this.name, animal: this.animal}
});
}
但是,当我在openDialog中控制台组件时,我的组件名称显示为简单字符串,而不是完整的组件Structure。
我已经在我的app.module的入口组件中添加了我的组件。
让我知道,即使我尝试的实现也是可能的。
谢谢。
答案 0 :(得分:1)
它显示为字符串,因为'ComponentA'是指字符串。您将具有import并将组件构造函数传递给对话框。然后在对话框组件中,注入ComponentFactoryResolver
服务和ViewContainerRef
以初始化该组件:
例如
parent.component.ts
import { ComponentA } from './component-a.component.ts';
import { ComponentB } from './component-b.component.ts';
class ParentComponent {
public ComponentA = ComponentA;
public ComponentB = ComponentB;
@ViewChild('dialog') dialog;
}
parent.component.html
<button mat-raised-button (click)="dialog.openDialog(ComponentA)">Component A</button>
<button mat-raised-button (click)="dialog.openDialog(ComponentB)">Component B</button>
dialog-box.component.ts
class DialogBoxComponent {
constructor(private viewRef: ViewContainerRef, private componentFactoryResolver: ComponentFactoryResolver) {
}
openDialog(componentConstructor) {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentConstructor);
const componentInstance = this.viewContainerRef.createComponent(componentFactory);
// add any initialisation you might need to do to componentInstance
}
}
请注意,以这种方式创建的组件将无法使用其@Input()
和@Output()
装饰器。这是角度编译器的局限性,它在设计上倾向于使用单态组件。
因此,您必须手动设置依赖于@Input()
的子组件的那些属性。对于@Output()
,您必须手动订阅组件上的任何事件侦听器。