如上图所示,我需要做一个功能,即点击某个按钮的时候我会传递一个组件给对话框,在点击submit的时候,我需要获取该组件内部的某个值
好,需求清楚了,那么来看核心代码:
ts
const config = {component: TestComponent,};
this._dialog.open(BasicDialogModalComponent, {data: config})
点击按钮的时候,我就会执行上述代码,把TestComponent
作为参数传递给BasicDialogModalComponent
好,看BasicDialogModalComponent
的核心代码
html
<div class="content">
<ng-container *ngIf="dialogData.component">
<div
#dynamicComponentContainer
*ngComponentOutlet="dialogData.component"
></div>
</ng-container>
</div>
ts
@ViewChild('dynamicComponentContainer', { read: ViewContainerRef, static: false })
public container!: ViewContainerRef;
private _dynamicComponentRef: ComponentRef<unknown> | null = null;
public ngAfterViewInit(): void {
this._loadDynamicComponent();
this._changeDetectorRef.detectChanges();
console.log('after init', this.container);
}
private _loadDynamicComponent(): void {
if (this.dialogData.component && this.container) {
this.container.clear();
this._dynamicComponentRef = this.container.createComponent(this.dialogData.component);
} else {
console.error('dialogData.component or container is null');
}
}
public submit(): void {
if (this._dynamicComponentRef) {
const componentInstance = this._dynamicComponentRef.instance;
const { modelValue } = componentInstance as { modelValue: unknown }; // 假设组件实例有一个 modelValue 属性
console.log('Dynamic component modelValue:', modelValue);
}
}
解释下代码:
html中*ngComponentOutlet="dialogData.component"
即把dilogData.component
作为一个组件直接输出到视图中,只要有这行代码,ts中不需要做任何操作,页面上可以正常显示,但是,如果想要获取组件中的值,则必须得使用ts中的@ViewChild
方法,拿到组件的内容。
那么这样能获取组件的内容吗,答案是不行
原因就在于*ngComponentOutlet="dialogData.component"
这段代码,在我们去掉这段代码,即html修改如下
<div class="content">
<ng-container *ngIf="dialogData.component">
<ng-container #dynamicComponentContainer></ng-container>
</ng-container>
</div>
这时候页面也能正常显示,并且能获取到组件的值
这是为什么呢?
原因很简单,如果使用*ngComponentOutlet="dialogData.component"
就会直接覆盖原本使用
this._dynamicComponentRef = this.container.createComponent(this.dialogData.component);
创建出来的组件,虽然页面上看起来并无不同
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。