在Angular中动态创建TemplateRef,并使用ViewChildren检索它们

在Angular中动态创建TemplateRef,并使用ViewChildren检索它们,angular,Angular,我想在另一个组件中创建一些动态组件,但不是一次,多次。这个数字也是动态的 因此,我使用ComponentFactoryResolver创建组件,然后使用ViewChild动态注入该组件。正如我所说的,问题是我需要在很多地方这样做,因此我需要使用ViewChildren检索所有引用并注入组件(使用特定的输入数据) 我把问题简化到我需要的程度。 我有一个组件,它被传递一个数据数组和要创建的组件的类型 @Component({ selector: 'my-app', template: `

我想在另一个组件中创建一些动态组件,但不是一次,多次。这个数字也是动态的

因此,我使用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;
}
@组件({
选择器:“我的应用程序”,
模板:`
`
})
导出类AppComponent{
行=[
{name:'data1'},
{name:'data2'},
{name:'data3'},
{name:'data4'}
];
组件=子组件;
}
在父级中,我显示一个表,其中数据中的每个元素都有一行作为参数接收,但我还希望在每行下面显示另一行,该行的一个组件也作为参数传递

举个例子,在所有行中,我对一个组件执行的正是这个操作,其中我传递name='TOTAL'。因此,我使用
检索引用并注入组件

我尝试对动态参照使用相同的方法,但它不起作用。我创建了一个指令主机,以便使用具有特定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';
  }

}
@指令({
选择器:“主机”
})
导出类主机{
@Input()id:string;
}
@组成部分({
选择器:“我的父母”,
模板:`
我的数据头
{{d.name}
`
})
导出类ParentComponent实现OnInit,AfterContentInit{
@输入()数据:任意;
@Input()内部:任意;
@ViewChildren(主机)主机:QueryList;
@ViewChild('entry',{read:ViewContainerRef})entry:ViewContainerRef;
构造函数(专用冲突解决程序:ComponentFactoryResolver){}
恩戈尼尼特(){
}
ngAfterViewInit(){
if(this.hosts){
const componentFactory=this.resolver.resolveComponentFactory(this.internal);
this.hosts.forEach(主机=>{
console.log(主机);
const component=host.createComponent(componentFactory);
component.instance.name=host.id;
});
}
}
ngAfterContentInit(){
const componentFactory=this.resolver.resolveComponentFactory(this.internal);
const component=this.entry.createComponent(componentFactory);
component.instance.name='TOTAL';
}
}
这里是

我检索到的主机元素似乎无法注入。 有什么好办法吗


谢谢。

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;
   });
  }
}