でテンプレートをカスタマイズする


本来のポストCustomize template with ngTemplateOutlet and ngTemplate in Angular

導入
角度のコンポーネントがプログラムによってngtemplateをレンダリングする必要があるとき、NGIFおよびそれ以外の構文はほとんどのシナリオの面倒を見ます.しかしながら、NGIFはNGTemplateExtractディレクティブをサポートするコンテキストが不足しています.いずれかのテンプレートが入力または計算されたコンポーネントのデータに依存する場合、NGTemplateExtractディレクティブのテンプレートコンテキストを介して値を渡すことができます.
ngtemplateoutの使用方法は次のようになります.
<ng-container 
   *ngTemplateOutlet="templateRefExp; context: contextExp">
</ng-container>
それは、1993年の構文上の砂糖です
<ng-container 
   [ngTemplateOutlet]="templateRefExp" 
   [ngTemplateOutletContext]="contextExp">
</ng-container>
この記事では、ngtemplateoutディレクティブを使用する方法を学びます<ng-container> 要素は、3進式の結果を与えられたディレクティブに異なるテンプレートを割り当てます.テンプレートコンテキストに入力を供給することができ、レンダリングされたNGTemplateは、コンテキスト内のデータを使用して、後でコンテンツをレンダリングできます.


NGContainerをカスタマイズする
まず、追加<ng-container> 食品メニューの要素.コンポーネント.HTMLはNGTemplateExtractディレクティブをホストします.ディレクティブは、三項式の結果に基づいてNGTemplateのインスタンスを受け取ります.式がtrueの場合、ディレクティブは“hasfood”テンプレートを取得します.一方、式が偽の場合、“nofood”テンプレートを取得します.
<ng-container *ngTemplateOutlet="data.menuItems.length > 0 ? hasFood : noFood; context: { data }"></ng-container>
また、データオブジェクトをテンプレートコンテキストに渡し、両方のテンプレートに対してその値にアクセスします.
context: { data }
情報については、データは2つのプロパティ:menuitemとオプションを持つオブジェクトです.MenuItemは、メニュー項目とその選択の情報を格納する配列です.オプションドロップダウンの選択した値を格納します.
data: {
   menuItems: [ 
     { question: '...', choices: [...] }, 
     { question: '...', choices: [...] } 
   ],
   option: 'AVAILABLE'
}

ngtemplateoutディレクティブに割り当てられるHasFoods NGtemplateを定義します
次に、条件、データのときに表示されるHasFoodテンプレートを定義します.menuitemlength>0である.
ngtemplateTailはコンテキスト式を持っているので、data =“data”によってコンテキスト内のデータオブジェクトにアクセスできます.次に、配列を繰り返して各メニュー項目を表示します<app-food-menu-card> コンポーネント.<app-food-question> ユーザーが質問をしながら食品を選択するプロンプト<app-food-choice> 入力フィールドを指定して数量を入力します.
<ng-template #hasFood let-data="data">
  <app-food-menu-card *ngFor="let menuItem of data.menuItems; index as i; trackBy: menuItemTrackByFn">
    <app-food-question [question]="menuItem.question" head>
    </app-food-question>
    <ng-container *ngFor="let choice of menuItem.choices; index as j; trackBy: choiceTrackByFn" body>
      <app-food-choice
        [choice]="choice"
        [qtyMap]="qtyMap"
        (foodChoiceAdded)="handleFoodChoiceSub$.next($event)"
      ></app-food-choice>
    </ng-container>
  </app-food-menu-card>
</ng-template>


ngtemplateoutディレクティブに割り当てるにはnfood ngtemplateを定義します
最初のngtemplateは準備ができていて、2番目のngtemplateを作成する必要があります.MenuItem配列に項目がない場合、このテンプレートは単純なテキストを示します.
<ng-template #noFood let-data="data">
   No food or drink that is {{ data.option | renderMenuOption }}.
</ng-template>
export enum MENU_OPTIONS {
  ALL = 'ALL',
  AVAILABLE = 'AVAILABLE',
  SOLD_OUT = 'SOLD_OUT',
  LOW_SUPPLY = 'LOW_SUPPLY',
}
あなたがデータに興味があるならば.オプションとして、MenuRenuオプションenumの値です.ENUMには4つのメンバー値があります.' all '、' available '、' lownum supply 'または' soldtle out 'は大文字です.メンバーの値とメンバー値のアンダースコア形式のため、我々は通常の英語の単語に値を変換するカスタムパイプを作成します.


ngtemplate nofoodの値を変換するカスタムパイプをビルドします
最後に、角のCLIを使用してカスタムパイプのボイラープレートコードを生成します
ng g pipe RenderOptionPipe
import { Pipe, PipeTransform } from '@angular/core'

import { MENU_OPTIONS } from '../enums'

@Pipe({
  name: 'renderMenuOption',
})
export class RenderOptionPipe implements PipeTransform {
  transform(value: MENU_OPTIONS): string {
    if (value === MENU_OPTIONS.AVAILABLE) {
      return 'available'
    } else if (value === MENU_OPTIONS.LOW_SUPPLY) {
      return 'low supply'
    }

    return 'sold out'
  }
}
三つの結果
  • すべての食物は売り切れになる
  • すべての食物は利用可能です(数量>0)
  • 食料は少ない


  • テンプレートの最終コード
    <div class="food-menu" *ngIf="menuItems$ | async as data; else notAvailable">
      <app-food-menu-option 
         (menuOptionSelected)="menuOptionSub$.next($event)">
      </app-food-menu-option>
      <ng-container *ngTemplateOutlet="data.menuItems.length > 0 ? hasFood : noFood; context: { data }"></ng-container>
    </div>
    
    <ng-template #notAvailable>No menu</ng-template>
    <ng-template #hasFood let-data="data">
      <app-food-menu-card *ngFor="let menuItem of data.menuItems; index as i; trackBy: menuItemTrackByFn">
        <app-food-question [question]="menuItem.question" head>
        </app-food-question>
        <ng-container *ngFor="let choice of menuItem.choices; index as j; trackBy: choiceTrackByFn" body>
          <app-food-choice
            [choice]="choice"
            [qtyMap]="qtyMap"
            (foodChoiceAdded)="handleFoodChoiceSub$.next($event)"
          ></app-food-choice>
        </ng-container>
      </app-food-menu-card>
    </ng-template>
    <ng-template #noFood let-data="data">
       No food or drink that is {{ data.option | renderMenuOption }}.
    </ng-template>
    


    最後の思考
    コンポーネントが条件テンプレートをレンダリングする必要がある場合、特にテンプレートがコンポーネントからの入力を期待しているときには、NGIFは正しいアプローチではないかもしれません.堅牢なソリューションは、NGコンテナ要素でNGTemplateExtractディレクティブをホストし、三項式でディレクティブにテンプレートとコンテキストを割り当てることです.
    3進式の結果は、どのテンプレートを表示するかを制御しますテンプレートはテンプレートコンテキスト内の変数にアクセスでき、要素の値を使用できます.
    これは、ブログのポストの終わりであり、私はあなたのコンテンツが好きで、角度や他の技術の私の学習経験に従ってください願っています.

    リソース
  • Repo: https://github.com/railsstudent/ng-spanish-menu
  • ngtemplateアウトレットドキュメント:https://angular.io/api/common/NgTemplateOutlet
  • ngtemplateoutput :カスタマイズの秘密https://indepth.dev/posts/1405/ngtemplateoutlet