我想创建一个在参数中另外一个的组件,并生成该组件的实例集合。
(最终的目标是创建一个通用的后台)。
例如,有类似的东西:
<common-collection [component]="collectionDisplayComponent" [items]="items"></common-collection>
我会得到这个(这里的组件是一个用于测试目的的加载器):
所以我已经有了一些工作(几乎):这里是组件的代码:
@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,因为我有这个错误:
我认为我应该填充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();
}
答案 0 :(得分:1)
试试这个:
constructor(private cd: ChangeDetectorRef) {
}
ngAfterViewInit() {
......
this.cd.detectChanges();
}
答案 1 :(得分:0)
你可以使用超时。
setTimeout(
this.widgetTargets.changes.subscribe(() => {
this.refresh()
})
,0);
答案 2 :(得分:0)
它将帮助您从打字稿中动态呈现组件
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;
}
}