在Angular中,如何对子列表进行内容投影?

问题描述 投票:0回答:2

我有一个组件应该接受 任意数量 已知类型的子组件,并在

*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>'

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

angular children ng-content
2个回答
4
投票

这是

ContentChildren
ngTemplateOutlet
的用例...像这样

首先你需要一个指令来标记和获取你想要渲染的任何孩子的模板参考:

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

然后将它添加到孩子们:

<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-container>
</div>

1
投票

解决了。您只能将

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>;
}
© www.soinside.com 2019 - 2024. All rights reserved.