在Angular中,如何对children列表做Content Projection?

In Angular, how to do Content Projection over the list of children?

我有一个组件应该接受 任意数量 的已知类型的子组件,并在 *ngFor 中使用额外的包装器呈现它们。或者,我可以传递并呈现 <ng-template> 的列表吗?

容器将这样使用:

<app-custom-container>
   <app-custom-child name="1">...</app-custom-child>
   <app-custom-child name="2">...</app-custom-child>
   <app-custom-child name="3">...</app-custom-child>
</app-custom-container>

内部容器模板我想做这样的事情:

template: '<div>
    <ng-container *ngFor="let child of ...?">
        <app-custom-child-internal-wrapper [id]="child.id">
             <ng-content/> <!--somehow only render this specific child-->
        </app-custom-child-internal-wrapper>
    </ng-content>
</div>'

可以做这个或类似的事情吗?

解决了。您可以仅将 CustomChildComponent 用于模板,如果使用 @ContentChildren(CustomChildComponent)

则获取列表

用法:

<app-custom-container>
   <app-custom-child name="1">
       <ng-template #innertemplate>
          ...
       </ng-temlate>
   </app-custom-child>
   <app-custom-child name="2">
       <ng-template #innertemplate>
            ...
       </ng-temlate>
   </app-custom-child>
</app-custom-container>

子组件:

@Component({
  selector:    'app-custom-child',
  template: '', // template empty by design
})
export class CustomChildComponent {
    @Input() public name!: string;
   
    @ContentChild('innertemplate', { read: TemplateRef }) 
    public innerTemplateReference!: TemplateRef<any>; 
}

父组件:

@Component({
  selector:    'app-custom-container',
  template: '<app-some-internal-container>
       <ng-container *ngFor="let child of contentChildren">
           <app-some-internal-wrapper>
               <ng-container ngTemplateOutlet="child.innerTemplateReference">
                    
               </ng-container>
           </app-some-internal-wrapper>
       </ng-container>
  </app-some-internal-container>', 
})
export class CustomContainerComponent {   
    @ContentChildren(CustomChildComponent) 
    public contentChildren: QueryList<CustomChildComponent>;
}

这是 ContentChildrenngTemplateOutlet 的用例...就像这样

首先你需要一个指令来标记和获取任何你想要呈现的 children 的模板引用:

@Directive({ selector: '[childMarker]'})
export class ChildMarkerDirective {
  constructor(public templateRef: TemplateRef<any>) { }
}

然后将其添加到 children:

<app-custom-container>
   <app-custom-child *childMarker name="1">...</app-custom-child>
   <app-custom-child *childMarker name="2">...</app-custom-child>
   <app-custom-child *childMarker name="3">...</app-custom-child>
</app-custom-container>

在您的自定义容器控制器中,您需要这样的东西来查询内容中的标记:

@ContentChildren(ChildMarkerDirective)
children

然后在您的模板中,您可以迭代和投影:

<div>
    <ng-container *ngFor="let child of children">
        <app-custom-child-internal-wrapper>
             <ng-container *ngTemplateOutlet="child.templateRef"></ng-container>
        </app-custom-child-internal-wrapper>
    </ng-content>
</div>