头图


如上图所示,我需要做一个功能,即点击某个按钮的时候我会传递一个组件给对话框,在点击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方法,拿到组件的内容。

那么这样能获取组件的内容吗,答案是不行
image.png

原因就在于*ngComponentOutlet="dialogData.component" 这段代码,在我们去掉这段代码,即html修改如下

    <div class="content">
      <ng-container *ngIf="dialogData.component">
        <ng-container #dynamicComponentContainer></ng-container>
      </ng-container>
    </div>

这时候页面也能正常显示,并且能获取到组件的值
image.png
这是为什么呢?

原因很简单,如果使用*ngComponentOutlet="dialogData.component" 就会直接覆盖原本使用

      this._dynamicComponentRef = this.container.createComponent(this.dialogData.component);

创建出来的组件,虽然页面上看起来并无不同


munergs
30 声望8 粉丝

现在即是最好。