【问题标题】:Create templateRefs dynamically in Angular and retrieve them with ViewChildren在 Angular 中动态创建 templateRefs 并使用 ViewChildren 检索它们
【发布时间】:2017-05-12 17:57:57
【问题描述】:

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

所以我使用 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'。所以我使用&lt;ng-container #entry&gt; 来检索引用并注入组件。

我尝试对动态引用进行相同的操作,但它不起作用。我创建了一个指令 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

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

谢谢。

【问题讨论】:

标签: angular


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2014-08-03
    • 1970-01-01
    • 2018-12-26
    • 2011-09-20
    • 2021-03-23
    • 2016-11-11
    • 1970-01-01
    • 2020-07-30
    • 2011-12-19
    相关资源
    最近更新 更多