在ngFor中动态添加组件 [英] Dynamically adding components in ngFor

查看:178
本文介绍了在ngFor中动态添加组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个仪表板",用于加载配置的元素. 仪表板模板具有以下内容:

I have a "dashboard" that loads configured elements. Dashboard template has this:

  <div class="dash-container" [ngGrid]="gridConfig">
    <div *ngFor="let box of boxes; let i = index"
       [(ngGridItem)]="box.config"
       (onItemChange)="updateItem(i, $event)"
       (onResize)="onResize(i, $event)"
       (onDrag)="onDrag(i, $event)"
       (onDragStop)="onDragStop(i,$event)"
       [ngClass]="box.class"
     >
      <div class="handle"><h4>{{box.title}}</h4></div>
      <div [innerHTML]= "box.content"></div>
    </div>
  </div>

现在<div [innerHTML]= "box.content"></div>将不起作用,因为非标准元素会被清除. 运行最新的Angular 2.4.6(RC 6).

Now <div [innerHTML]= "box.content"></div> will not work because non standard elements get sanitised. Running latest Angular 2.4.6 (RC 6).

我看了一些可以为动态组件找到的示例-但我所看到的只是它们只是将组件添加到当前组件中-但我需要一个非常特定的div,就像上面的示例一样.

I look at the examples i could find for dynamic components - but all i see is that they just add components to the current component - but i need them in a very specific divs like in the example above.

ComponentFactoryResolver通常与@ViewChild一起使用. 但是我不能只在一个循环中这样做:

ComponentFactoryResolver is often used together with @ViewChild. But i can't just do this inside a loop:

ngAfterViewInit() {
    const dashWidgetsConf = this.widgetConfigs();
    for (var i = 0; i < dashWidgetsConf.length; i++) {
      const conf = dashWidgetsConf[i];

      @ViewChild(conf.id, {read: ViewContainerRef}) var widgetTarget: ViewContainerRef;

      var widgetComponent = this.componentFactoryResolver.resolveComponentFactory(UnitsComponent);
      widgetTarget.createComponent(widgetComponent);
    }
  }

@viewchild给出装饰器在这里无效". 如何从conf列表中加载组件(循环)并将其添加到组件中的特定div(divs #{{conf.id}})内?

The @viewchild gives 'Decorators are not valid here'. How can i load components from a conf list (in a loop) and add them inside a specific div (divs got #{{conf.id}}) in my component?

推荐答案

经过研究,这是我想出的解决方案(适用于angular 4.0.0).

After some research, this is the solution i came up with (works in angular 4.0.0).

通过ID加载所有ViewContainerRef目标:

Load all the ViewContainerRef targets by id:

@ViewChildren('dynamic', {read: ViewContainerRef}) public widgetTargets: QueryList<ViewContainerRef>;

然后遍历它们以获取目标,为组件创建工厂并调用createComponent.
也可以使用组件引用来订阅或设置其他组件属性.

Then loop over them to get the target, create a factory for the component and call createComponent.
Also can use the component reference to subscribe or set other component properties.

ngAfterViewInit() {
    const dashWidgetsConf = this.widgetConfigs();
    const widgetComponents = this.widgetComponents();
    for (let i = 0; i < this.widgetTargets.toArray().length; i++) {
        let conf = dashWidgetsConf[i];
        let component = widgetComponents[conf.id];
        if(component) {
            let target = this.widgetTargets.toArray()[i];
            let widgetComponent = this.componentFactoryResolver.resolveComponentFactory(component);
            let cmpRef: any = target.createComponent(widgetComponent);

            if (cmpRef.instance.hasOwnProperty('title')) {
                cmpRef.instance.title = conf.title;
            }
        }
    }
}

widgetComponents是对象{key: component},而widgetConfigs是我存储特定组件信息的位置-如标题,组件ID等.

The widgetComponents is a object {key: component} and widgetConfigs is where i store specific component info - like title, component id etc.

然后进入模板:

<div *ngFor="let box of boxes; let i = index" >
    <ng-template #dynamic></ng-template>
</div>

目标的顺序与conf中的顺序相同(从中生成boxes),这就是为什么我可以按顺序循环遍历它们并使用i作为索引来获取正确的conf和组件的原因.

And the order of targets is the same as in my conf ( boxes is generated from it) - which is why i can loop through them in order and use i as index to get the correct conf and component.

这篇关于在ngFor中动态添加组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆