如何有条件地将 <ng-content> 换行多次?
How do I conditionally wrap <ng-content> multiple times?
我尝试编写一个包装器组件,它可以传递一些文本和一些参数,然后根据这些参数使用 bootstrap 格式化我的文本。
我试过这个:
header-line.component.ts
@Component({
selector:'header-line',
templateUrl: 'header-line.component.html'
})
export class HeaderLineComponent {
@Input level: number;
// other inputs used for formatting skipped here
}
header-line.component.html
<div class="row">
<div class="col-sm-12"> <!-- would really be [className]="..." based on skipped inputs -->
<header-wrapper [level]="level">
<!-- display of icon, based on skipped inputs -->
<ng-content></ng-content>
</header-wrapper>
</div>
</div>
header-wrapper.component.ts
@Component({
selector: 'header-wrapper',
templateUrl: './header-wrapper.component.html'
})
export class HeaderWrapperComponent {
@Input() level: number;
}
header-wrapper.component.html
<h1 *ngIf="level === 1"><ng-content></ng-content></h1>
<h2 *ngIf="level === 2"><ng-content></ng-content></h2>
<h3 *ngIf="level === 3"><ng-content></ng-content></h3>
<h4 *ngIf="level === 4"><ng-content></ng-content></h4>
<h5 *ngIf="level === 5"><ng-content></ng-content></h5>
<span *ngIf="!level || level < 1 || level > 5"><ng-content></ng-content></span>
预期用途
用法大致如下:
<header-line [level]="1" [...]="...">Just a test h1</header-line>
<header-line [level]="2" [...]="...">Just a test h2</header-line>
<header-line [level]="3" [...]="...">Just a test h3</header-line>
<header-line [...]="...">Just a test span</header-line>
预期输出
然后我会期望输出创建等同于:
<div class="row">
<div class="cols-sm-12">
<h1>Just a test h1</h1>
</div>
</div>
<div class="row">
<div class="cols-sm-12">
<h2>Just a test h2</h2>
</div>
</div>
<div class="row">
<div class="cols-sm-12">
<h3>Just a test h3</h3>
</div>
</div>
<div class="row">
<div class="cols-sm-12">
<span>Just a test span</span>
</div>
</div>
有效输出
然而,我得到的是:
<div class="row">
<div class="cols-sm-12">
</div>
</div>
<div class="row">
<div class="cols-sm-12">
</div>
</div>
<div class="row">
<div class="cols-sm-12">
</div>
</div>
<div class="row">
<div class="cols-sm-12">
<span>Just a test span</span>
</div>
</div>
问题分析
我花了一点时间才发现问题的原因是重复使用 in header-wrapper.component.ts 因为它显然是静态的,不能动态使用。
以下两个 link 解释了为什么我的期望落空了:
https://github.com/angular/angular/issues/9173
https://github.com/angular/angular/issues/8563
寻找解决方案
Whosebug 上的以下 link 显示了如果只需要支持两种情况如何做到这一点:
使用这种方法我管理了以下内容:
更新:header-wrapper.component.html
<h1 *ngIf="level && level === 1; else notOne">
<ng-container *ngTemplateOutlet="content"></ng-container>
</h1>
<ng-template #notOne>
<h2 *ngIf="level && level === 2; else notTwo">
<ng-container *ngTemplateOutlet="content"></ng-container>
</h2>
</ng-template>
<ng-template #notTwo>
<h3 *ngIf="level && level === 3; else notThree">
<ng-container *ngTemplateOutlet="content"></ng-container>
</h3>
</ng-template>
<ng-template #notThree>
<h4 *ngIf="level && level === 4; else notFour">
<ng-container *ngTemplateOutlet="content"></ng-container>
</h4>
</ng-template>
<ng-template #notFour>
<h5 *ngIf="level && level === 5; else content">
<ng-container *ngTemplateOutlet="content"></ng-container>
</h5>
</ng-template>
<ng-template #content>
<ng-content></ng-content>
</ng-template>
这会产生所需的输出。
我的问题
这真的是唯一的方法吗?还是我缺少更简单的方法?
根据 Jota.Toledo 链接的视频,我想出了一个更紧凑的版本。
已更新 header-wrapper.component.html
<h1 *ngIf="level && level === 1"><ng-container [ngTemplateOutlet]="content"></ng-container></h1>
<h2 *ngIf="level && level === 2"><ng-container [ngTemplateOutlet]="content"></ng-container></h2>
<h3 *ngIf="level && level === 3"><ng-container [ngTemplateOutlet]="content"></ng-container></h3>
<h4 *ngIf="level && level === 4"><ng-container [ngTemplateOutlet]="content"></ng-container></h4>
<h5 *ngIf="level && level === 5"><ng-container [ngTemplateOutlet]="content"></ng-container></h5>
<span *ngIf="!level || level < 1 || level > 5"><ng-container [ngTemplateOutlet]="content"></ng-container></span>
这与我从问题中更新的解决方案一样有效,但我发现这个版本更紧凑,更易于阅读。
我尝试编写一个包装器组件,它可以传递一些文本和一些参数,然后根据这些参数使用 bootstrap 格式化我的文本。
我试过这个:
header-line.component.ts
@Component({
selector:'header-line',
templateUrl: 'header-line.component.html'
})
export class HeaderLineComponent {
@Input level: number;
// other inputs used for formatting skipped here
}
header-line.component.html
<div class="row">
<div class="col-sm-12"> <!-- would really be [className]="..." based on skipped inputs -->
<header-wrapper [level]="level">
<!-- display of icon, based on skipped inputs -->
<ng-content></ng-content>
</header-wrapper>
</div>
</div>
header-wrapper.component.ts
@Component({
selector: 'header-wrapper',
templateUrl: './header-wrapper.component.html'
})
export class HeaderWrapperComponent {
@Input() level: number;
}
header-wrapper.component.html
<h1 *ngIf="level === 1"><ng-content></ng-content></h1>
<h2 *ngIf="level === 2"><ng-content></ng-content></h2>
<h3 *ngIf="level === 3"><ng-content></ng-content></h3>
<h4 *ngIf="level === 4"><ng-content></ng-content></h4>
<h5 *ngIf="level === 5"><ng-content></ng-content></h5>
<span *ngIf="!level || level < 1 || level > 5"><ng-content></ng-content></span>
预期用途
用法大致如下:
<header-line [level]="1" [...]="...">Just a test h1</header-line>
<header-line [level]="2" [...]="...">Just a test h2</header-line>
<header-line [level]="3" [...]="...">Just a test h3</header-line>
<header-line [...]="...">Just a test span</header-line>
预期输出
然后我会期望输出创建等同于:
<div class="row">
<div class="cols-sm-12">
<h1>Just a test h1</h1>
</div>
</div>
<div class="row">
<div class="cols-sm-12">
<h2>Just a test h2</h2>
</div>
</div>
<div class="row">
<div class="cols-sm-12">
<h3>Just a test h3</h3>
</div>
</div>
<div class="row">
<div class="cols-sm-12">
<span>Just a test span</span>
</div>
</div>
有效输出
然而,我得到的是:
<div class="row">
<div class="cols-sm-12">
</div>
</div>
<div class="row">
<div class="cols-sm-12">
</div>
</div>
<div class="row">
<div class="cols-sm-12">
</div>
</div>
<div class="row">
<div class="cols-sm-12">
<span>Just a test span</span>
</div>
</div>
问题分析
我花了一点时间才发现问题的原因是重复使用 in header-wrapper.component.ts 因为它显然是静态的,不能动态使用。
以下两个 link 解释了为什么我的期望落空了:
https://github.com/angular/angular/issues/9173
https://github.com/angular/angular/issues/8563
寻找解决方案
Whosebug 上的以下 link 显示了如果只需要支持两种情况如何做到这一点:
使用这种方法我管理了以下内容:
更新:header-wrapper.component.html
<h1 *ngIf="level && level === 1; else notOne">
<ng-container *ngTemplateOutlet="content"></ng-container>
</h1>
<ng-template #notOne>
<h2 *ngIf="level && level === 2; else notTwo">
<ng-container *ngTemplateOutlet="content"></ng-container>
</h2>
</ng-template>
<ng-template #notTwo>
<h3 *ngIf="level && level === 3; else notThree">
<ng-container *ngTemplateOutlet="content"></ng-container>
</h3>
</ng-template>
<ng-template #notThree>
<h4 *ngIf="level && level === 4; else notFour">
<ng-container *ngTemplateOutlet="content"></ng-container>
</h4>
</ng-template>
<ng-template #notFour>
<h5 *ngIf="level && level === 5; else content">
<ng-container *ngTemplateOutlet="content"></ng-container>
</h5>
</ng-template>
<ng-template #content>
<ng-content></ng-content>
</ng-template>
这会产生所需的输出。
我的问题
这真的是唯一的方法吗?还是我缺少更简单的方法?
根据 Jota.Toledo 链接的视频,我想出了一个更紧凑的版本。
已更新 header-wrapper.component.html
<h1 *ngIf="level && level === 1"><ng-container [ngTemplateOutlet]="content"></ng-container></h1>
<h2 *ngIf="level && level === 2"><ng-container [ngTemplateOutlet]="content"></ng-container></h2>
<h3 *ngIf="level && level === 3"><ng-container [ngTemplateOutlet]="content"></ng-container></h3>
<h4 *ngIf="level && level === 4"><ng-container [ngTemplateOutlet]="content"></ng-container></h4>
<h5 *ngIf="level && level === 5"><ng-container [ngTemplateOutlet]="content"></ng-container></h5>
<span *ngIf="!level || level < 1 || level > 5"><ng-container [ngTemplateOutlet]="content"></ng-container></span>
这与我从问题中更新的解决方案一样有效,但我发现这个版本更紧凑,更易于阅读。