在NgFor中添加动态组件

问题描述 投票:1回答:3

我想创建一个在参数中使用另一个组件的组件,并生成该组件的实例集合。

(最终的目标是创建一个通用的后台)。

例如,有这样的东西:

<common-collection [component]="collectionDisplayComponent" [items]="items"></common-collection>

我会得到这个(这里的组件是一个用于测试目的的加载器):

enter image description here

所以我已经有了一些工作(差不多):这里是组件的代码:

@Component({
  selector: 'common-collection',
  templateUrl: 'collection.component.html',
  styleUrls:  ['collection.component.css'],
  providers: [  ]

})
export class CollectionComponent implements AfterViewInit{

    constructor(private componentFactoryResolver: ComponentFactoryResolver) { }

    @Input()
    set items(items: Array<object>){
      this._items = items;
      this.refresh();
    }

    private _items: Array<object> = [];screen
    @ViewChildren('componentRef', {read: ViewContainerRef}) public widgetTargets: QueryList<ViewContainerRef>

    public refresh() {
      let component = LoaderComponent; // Should be given in parameter, set manually for now

      if(typeof(this.widgetTargets) !== "undefined"){

        for (let i = 0; i < this.widgetTargets.toArray().length; i++) {
            let target = this.widgetTargets.toArray()[i];
            let widgetComponent = this.componentFactoryResolver.resolveComponentFactory(component);
            let cmpRef: any = target.createComponent(widgetComponent);


        }
      }
    }

    ngAfterViewInit(): void {
      this.widgetTargets.changes.subscribe(() => {
        this.refresh()
      });
    }
}

并且模板代码关联:

<div id="div-container">
    <div fxLayout="row" fxLayoutWrap fxLayoutGap="1%" fxFlexAlign="center center">
        <div class="div-item-card" fxFlex="24"  *ngFor="let item of _items;">
            <div #componentRef></div>
        </div>
    </div>
</div>

这段代码有效,但问题是我在错误的时间设置了viewChildren,因为我有这个错误:

enter image description here

我想我应该填充widgetTargets变量并在其上执行ngFor而不是_items,但我没有找到任何直接在其中添加组件的示例。

所有的例子都包括创建“void”dom元素,然后用组件工厂设置它们(我在那里做它并导致错误)。

非常感谢你的帮助。

编辑:“items”变量在组件init之后设置:它从异步调用加载到父组件中的数据库。

EDIT2在刷新方法中使用类似的东西。

for (let i = 0; i < this.widgetTargets.toArray().length; i++) {
            let target = this.widgetTargets.toArray()[i];
            let widgetComponent = this.componentFactoryResolver.resolveComponentFactory(component);
            target.clear();
            let cmpRef: any = target.createComponent(widgetComponent);
            cmpRef.instance.value = this._items[i]["value"];
            this.cd.detectChanges();
        }
angular
3个回答
1
投票

试试这个:

constructor(private cd: ChangeDetectorRef) {
}

ngAfterViewInit() {
   ......
    this.cd.detectChanges();
}

0
投票

你可以使用超时。

setTimeout(
  this.widgetTargets.changes.subscribe(() => {
    this.refresh()
  })
,0);

0
投票

它将帮助您从typescript动态呈现组件

    var data=[{"cardStyle1":LineChartComponent},{"cardStyle2":BarChartComponent}]
   loadComponent(){ 
        for(var i=0;i<data.length;i++){
         const componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.getComponentForCardType(data[i].name));

         let viewContainerRef = this.componentBind.viewContainerRef;

         const componentRef = viewContainerRef.createComponent(componentFactory);
         (<ImportcomponentComponent>componentRef.instance).datasource = this.datasourceData;
        }
}
© www.soinside.com 2019 - 2024. All rights reserved.