在ngFor中动态添加组件 [英] Dynamically adding components in 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屋!