【问题标题】:how to stop repeat initialisation when using dynamicComponentContainer使用动态组件容器时如何停止重复初始化
【发布时间】:2025-12-13 17:20:05
【问题描述】:

我有一个循环遍历组件列表并从列表中加载组件的布局。 为了实现这一点,我使用了动态组件,因为我需要一种动态的方式来注入从对象定义的组件。

如果我单击一个动态加载的组件,它会运行动态组件 2、3、4 次。我不明白为什么在子组件中的一个偶数之后我会重新初始化我的组件。有没有办法阻止这种情况,或者应该如何动态注入组件。

这是我发现动态注入组件并能够将数据传递给子组件的唯一方法,因为当前处于角度 4 的 ngComponentOutlet 不允许您从创建的组件中传递和检索数据并注入子组件。

Plunker:http://plnkr.co/edit/vslspJ?p=preview

@Component({
  selector: 'my-app',
  template: `
    <div>

      <buttons (passdata)="getthis($event)" ></buttons>

      <button (click)="loadDogs()">Load Dogs</button>
      <hr />


      <div *ngFor="let comp of componentlist">

        <dynamic-component [componentData]="configureWidget(comp)"></dynamic-component>
      </div>
      <hr />


    </div>
  `,
})



export class AppComponent {


  componentlist:any = [
      { name: 'dogs', component: dogsComponent, inputName: 'colordata',   inputvalue: 'zzz' },
      { name: 'cats', component: catsComponent, inputName: 'showNum',  inputvalue: 'zzz' }
    ]

  configureWidget(widget){
    console.log(widget)

  if(widget.name == 'dogs'){
        return  this.componentData = {
                  component: widget.component,
                  inputs: {
                   showNum : 'ddddd',

                  }
                };
  }  
  if(widget.name == 'cats'){
        return  this.componentData = {
                  component: widget.component,
                  inputs: {
                   colordata : 'ddddd',

                  }
                };
  }      

  }

【问题讨论】:

  • 你的代码太混乱了。 @Input() 设置组件数据。每当您设置 componentData 时,您都会创建一个新组件,并且正如我所见,您多次设置 componentData。我建议你删除 setter 方法。使用接口而不是使用类似这样的东西:componentData(data: {component: any, inputs: any })
  • @Omeralper,你能详细说明一下吗?你的意思是改用接口?
  • 这只是对代码可读性的建议。 componentData(data: CustomType) interface CustomType {component: any, inputs: any };
  • 初始化怎么样?它会一直这样做吗?

标签: angular typescript initialization components dynamically-generated


【解决方案1】:

问题在于AppComponent 以及您如何将componentData 传递给动态组件。 Angular 的更改检测知道 variable 是否已更改,但无法判断您是否在模板中使用了函数。

所以不要使用函数来传递处理过的数据,否则changeDetection会调用该函数,再次处理数据并传递它,它会在dynamic-component中调用你的setter函数并再次初始化。

Fixed Plunker

代码:

configuredWidgets = {};

  constructor(){
    this.componentlist.forEach(comp => {
      console.log(comp)

      if(comp.name == 'dogs'){
            this.configuredWidgets['dogs'] = {
                      component: comp.component,
                      inputs: {
                       showNum : 'ddddd',

                      }
                    };
      }  
      if(comp.name == 'cats'){
            this.configuredWidgets['cats'] = {
                      component: comp.component,
                      inputs: {
                       colordata : 'ddddd',

                      }
                    };
      }      

    })
  }

【讨论】: