显示我使用@ContentChildren 或@ViewChild 获取的组件的内容

Displaying content of Component that i fetched with @ContentChildren or @ViewChild

所以我试图在我的组件中的特定位置显示子组件。

我有以下内容:

@Component({
  selector: 'app-item-list',
  template: `
<p *ngFor="let item of items">
  {{item.order}}
  <!-- display content of child component here -->
</p>`
})
export class ItemListComponent implements OnInit, AfterContentInit {

  //Get all child components of the type ItemComponent and store them.
  @ContentChildren(ItemComponent, {descendants: true}) 
  items?: QueryList<ItemComponent>;
  constructor() { }

  ngOnInit() {
  }
    
  ngAfterContentInit(): void {
      
  }

}

@Component({
  selector: 'app-item',
  template: `
<p>
  item works!
</p>
<ng-content></ng-content>
`
})
export class ItemComponent implements OnInit {

  @Input() order?: string;
  constructor() { }

  ngOnInit() {
  }

}

我尝试使用 <ng-content select="item"> 显示它,但没有成功。

具有以下内容:

<app-item-list>
  <app-item order="2">
    test2
  </app-item>
  <app-item order="1">
    test1
  </app-item>
</app-item-list>

预期输出是

2
item works!
test2
1
item works!
test1

https://stackblitz.com/edit/angular-ivy-2aibgt

看看this。之前我以为没有办法实现你的输出,但我终于想通了。

我所做的是消除 @ContentChildren 方法,并将其替换为从 app 组件传递的 items Input。我遍历了项目,显示了顺序和相应的 app-item 组件。

我可以向您推荐 Angular material 库中使用的解决方案。

  • app-item 组件的内容包装在 <ng-template> 标签中

item.component.html

<ng-template>  <----------------------------- wrapper
  <p>
    item works!
  </p>
  <ng-content></ng-content>
</ng-template>
  • 然后我们可以获取对那个的引用 TemplateRef

item.component.ts

@ViewChild(TemplateRef, {static: true}) template: TemplateRef<any>;
  • 最后我们可以在 app-item-list 组件的循环中使用它

item-list.component.html

<p *ngFor="let item of items">
  {{item.order}}
  <ng-template [ngTemplateOutlet]="item.template"></ng-template>
</p>

Forked Stackblitz

确实没有办法使用 ng-content 来实现这一点(据我所知)。 ng-content 仅用于静态内容投影。

看看这里的用例 - https://github.com/angular/angular/issues/8563 - 第 2 段确认了一个事实,即你必须使用带有 viewref 的查询来做你想做的事情,即@yurzui 提供的解决方案。

您始终可以使用 selector 静态地 select 您想要投影的内容的哪一部分,但我怀疑这不是您要找的:

<ng-content select="[order=2]">
</ng-content>
<ng-content select="[order=1]">
</ng-content>

您可能错过了在 item-list.component.html

中添加 select 项目引用变量

item.component.html

<p>item works</p>
<ng-content select="[body]">
</ng-content>

item-list.component.html

<p *ngFor="let item of items">
  <app-item >
  <div body>
      {{item.order}}
  </div>
  </app-item>
  test2
</p>

参考:Stackblitz example