1

いくつかのテキストといくつかのパラメーターを渡すことができるラッパーコンポーネントを作成しようとしました。これにより、これらのパラメーターに基づいて、ブートストラップを使用してテキストがフォーマットされます。

私はこれを試しました:

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
}

ヘッダー行.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>

問題分析

私の問題の原因が header-wrapper.component.ts での繰り返しの使用であることを知るのに少し時間がかかりました。これは明らかに静的であり、動的に使用できないためです。

次の 2 つのリンクは、私の期待が裏切られた理由を説明しています。

https://github.com/angular/angular/issues/9173

https://github.com/angular/angular/issues/8563

解決策を見つける

Stackoverflow の次のリンクは、2 つのケースのみをサポートする必要がある場合にこれを行う方法を示しています。

ng-content を条件付きで div でラップする方法

そのアプローチを使用して、次のことを管理しました。

更新: 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>

これにより、目的の出力が生成されます。

私の質問

これは本当にこれを行う唯一の方法ですか?または、私が見逃している簡単な方法はありますか?

4

1 に答える 1