我想在另一个组件中创建一些动态组件,但不是一次,多次。而这个数字也是动态的。
所以我使用ComponentFactoryResolver创建组件,然后使用ViewChild动态注入该组件。正如我所说,问题是我需要在很多地方这样做,所以我需要使用ViewChildren来检索所有引用并注入组件(带有一定的输入数据)。
我有一个吸尘器,我把问题减少到我需要的地方。我有一个组件,它传递一个数据数组和要创建的组件的类型。
@Component({
selector: 'my-app',
template: `
<div>
<my-parent [data]="rows" [inner]="component">
</my-parent>
</div>
`
})
export class AppComponent {
rows = [
{ name: 'data1' },
{ name: 'data2' },
{ name: 'data3' },
{ name: 'data4' }
];
component = ChildComponent;
}
在my-parent中,我为接收到的数据中的每个元素显示一个表作为参数,但是,我想在每行下面显示另一行,该类型的组件也作为参数传递。
作为一个例子,上面所有的行我正在为一个组件做这个确切的事情,我传递name ='TOTAL'。所以我使用<ng-container #entry>
来检索引用并注入组件。
我尝试动态参考相同,它不起作用。我创建了一个指令Host,以便我可以使用具有特定id的ViewChildren检索它,但是当我尝试动态创建组件时,它不起作用。
这是代码
@Directive({
selector: 'host'
})
export class Host {
@Input() id: string;
}
@Component({
selector: 'my-parent',
template: `
<table>
<thead>
<tr>
<th>my data header</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<ng-container #entry></ng-container>
</td>
</tr>
<ng-container *ngFor="let d of data; let i = index;">
<tr>
<td>{{ d.name }}</td>
</tr>
<tr>
<td>
<host id="{{i}}"></host>
</td>
</tr>
</ng-container>
</tbody>
</table>
`
})
export class ParentComponent implements OnInit, AfterContentInit {
@Input() data: any;
@Input() inner: any;
@ViewChildren(Host) hosts: QueryList<Host>;
@ViewChild('entry', { read: ViewContainerRef }) entry: ViewContainerRef;
constructor(private resolver: ComponentFactoryResolver) {}
ngOnInit() {
}
ngAfterViewInit() {
if (this.hosts) {
const componentFactory = this.resolver.resolveComponentFactory(this.inner);
this.hosts.forEach(host => {
console.log(host);
const component = host.createComponent(componentFactory);
component.instance.name = host.id;
});
}
}
ngAfterContentInit() {
const componentFactory = this.resolver.resolveComponentFactory(this.inner);
const component = this.entry.createComponent(componentFactory);
component.instance.name = 'TOTAL';
}
}
这是plunker
似乎我检索的主机元素不能注入。有什么想法来解决它吗?
谢谢。
将ViewContainerRef
注入主机指令:
@Directive({
selector: 'host'
})
export class Host {
constructor(private viewRef: ViewContainerRef) {}
@Input() id: string;
}
之后做host.viewRef.createComponent(componentFactory)
ngAfterViewInit() {
if (this.hosts) {
const componentFactory = this.resolver.resolveComponentFactory(this.inner);
this.hosts.forEach(host => {
console.log(host);
const component = host.viewRef.createComponent(componentFactory);
component.instance.name = host.id;
});
}
}