如何循环遍历节元素以使用 ng-content 进行投影
How to loop through section elements to project with ng-content
我正在构建步进器并使用 "transclusion" 和 ng-content
来动态抓取步进器标记内的 section
元素。 stepper.component 视图是这样工作的:
<ng-content select=".one"></ng-content>
<ng-content select=".two"></ng-content>
<ng-content select=".three"></ng-content>
组件用法如下所示:
<stepper>
<section class="one">content here<section>
<section class="two">content here<section>
<section class="three">content here<section>
</stepper>
但是,我想通过自动识别节元素使其动态化:
<ng-content *ngFor="let section of sections; index as i;" select="['section:nth-child(' + i + ')']"></ng-content>
我怎样才能:
- 获取可用于嵌入的部分元素的节点列表?
- 使用 ng-content 的
select
逐步定位他们?
我会创建一个像这样的指令:
@Directive({
selector: '[stepper-section]'
})
export class StepperSectionDirective {}
然后向每个部分添加 stepper-section
属性:
<stepper>
<section stepper-section>content here<section>
<section stepper-section>content here<section>
<section stepper-section>content here<section>
</stepper>
最后使用 @ContentChildren
装饰器查询所有部分:
@ContentChildren(StepperSectionDirective) sections: QueryList<StepperSectionDirective>;
如果你想遍历内容并动态渲染它,你可以用 ng-template
包装你的 children 并使用 ngTemplateOutlet
指令在 StepperComponent 中渲染它们:
html
<app-stepper>
<ng-template stepper-section>Content 1</ng-template>
<ng-template stepper-section>Content 2</ng-template>
<ng-template stepper-section>Content 3</ng-template>
</app-stepper>
stepper-section.directive.ts
@Directive({
selector: '[stepper-section]'
})
export class StepperSectionDirective {
hidden = false;
constructor(public templateRef: TemplateRef<any>) {}
}
stepper.component.ts
@ContentChildren(StepperSectionDirective) sectionDirs: QueryList<StepperSectionDirective>;
stepper.component.html
<button *ngFor="let section of sections; index as i;"
[class.enabled]="activeSection === i" (click)="goTo(i)">
Step {{ i + 1 }}
</button>
<div class="content">
<ng-container *ngFor="let section of sections">
<ng-template *ngIf="!section.hidden"
[ngTemplateOutlet]="section.templateRef"></ng-template>
</ng-container>
</div>
这两种方法的区别在于,在第一种情况下,所有 child 内容都会被渲染,而我们只对 display: none
我们想要隐藏的步骤进行操作。
在第二种方法中,我们可以更好地控制要渲染的内容,并且我们只在特定时间渲染一个步骤。
我正在构建步进器并使用 "transclusion" 和 ng-content
来动态抓取步进器标记内的 section
元素。 stepper.component 视图是这样工作的:
<ng-content select=".one"></ng-content>
<ng-content select=".two"></ng-content>
<ng-content select=".three"></ng-content>
组件用法如下所示:
<stepper>
<section class="one">content here<section>
<section class="two">content here<section>
<section class="three">content here<section>
</stepper>
但是,我想通过自动识别节元素使其动态化:
<ng-content *ngFor="let section of sections; index as i;" select="['section:nth-child(' + i + ')']"></ng-content>
我怎样才能:
- 获取可用于嵌入的部分元素的节点列表?
- 使用 ng-content 的
select
逐步定位他们?
我会创建一个像这样的指令:
@Directive({
selector: '[stepper-section]'
})
export class StepperSectionDirective {}
然后向每个部分添加 stepper-section
属性:
<stepper>
<section stepper-section>content here<section>
<section stepper-section>content here<section>
<section stepper-section>content here<section>
</stepper>
最后使用 @ContentChildren
装饰器查询所有部分:
@ContentChildren(StepperSectionDirective) sections: QueryList<StepperSectionDirective>;
如果你想遍历内容并动态渲染它,你可以用 ng-template
包装你的 children 并使用 ngTemplateOutlet
指令在 StepperComponent 中渲染它们:
html
<app-stepper>
<ng-template stepper-section>Content 1</ng-template>
<ng-template stepper-section>Content 2</ng-template>
<ng-template stepper-section>Content 3</ng-template>
</app-stepper>
stepper-section.directive.ts
@Directive({
selector: '[stepper-section]'
})
export class StepperSectionDirective {
hidden = false;
constructor(public templateRef: TemplateRef<any>) {}
}
stepper.component.ts
@ContentChildren(StepperSectionDirective) sectionDirs: QueryList<StepperSectionDirective>;
stepper.component.html
<button *ngFor="let section of sections; index as i;"
[class.enabled]="activeSection === i" (click)="goTo(i)">
Step {{ i + 1 }}
</button>
<div class="content">
<ng-container *ngFor="let section of sections">
<ng-template *ngIf="!section.hidden"
[ngTemplateOutlet]="section.templateRef"></ng-template>
</ng-container>
</div>
这两种方法的区别在于,在第一种情况下,所有 child 内容都会被渲染,而我们只对 display: none
我们想要隐藏的步骤进行操作。
在第二种方法中,我们可以更好地控制要渲染的内容,并且我们只在特定时间渲染一个步骤。