web-dev-qa-db-ja.com

* ngTemplateOutletディレクティブの実際のシナリオは何ですか?

*ngTemplateOutletディレクティブについて読んでいました。このディレクティブの使用は、テンプレート参照とコンテキストオブジェクトをパラメーターとして動的にテンプレートをインスタンス化することです。

私が知りたいのは、Angularには次のような* ngTemplateOutletと同じ結果を達成するために非常に多くのものが含まれているということです。

  1. 同じコンポーネント内のコンポーネント変数値に基づいて異なるテンプレートをレンダリングできる複数の*ngIfを使用できます。同様に、[ngSwitch]があり、異なる値に基づいて異なるテンプレートがレンダリングされます。

  2. それぞれの変数のテンプレート参照変数を参照することにより、*ngIfを使用した参照を使用できます。

前者の場合:

<div *ngIf="condition1"> Content 1 </div>
<div *ngIf="condition2"> Content 2 </div>
<div *ngIf="condition3"> Content 3 </div>

そして後者の場合:

<ng-container *ngIf="condition then myTemplate else otherTemplate"></ng-container>
<ng-template #myTemplate> Some content... </ng-template>
<ng-template #otherTemplate> Some content... </ng-template>

私たちの武器にそのようなメソッドがある場合、*ngTemplateOutletはどのような値を追加しますか?

上記のメソッドを使用できず、*ngTemplateOutletディレクティブを使用する必要がある実際の使用例(ある場合)は何ですか?それとも同じ結果を達成するために選択する別の方法ですか?

13
patrick.1729

Angular テンプレートアウトレット は、ループによって生成されない、または条件の影響を受けないビューのさまざまなセクションに共通のテンプレートを挿入するために使用できます。たとえば、会社のロゴのテンプレートを定義して、ページのいくつかの場所に挿入できます。

<div>
  <ng-container *ngTemplateOutlet="companyLogoTemplate"></ng-container>
  <h1>Company History</h1>
  <div>{{companyHistory}}</div>
</div>
<form (ngSubmit)="onSubmit()">
  <ng-container *ngTemplateOutlet="companyLogoTemplate"></ng-container>
  <h1>User info</h1>
  <label>Name:</label><input type="text" [(ngModel)]="userName" />
  <label>Account ID:</label><input type="text" [(ngModel)]="accountId" />
  <button>Submit</button>
</form>
<div class="footer">
  <ng-container *ngTemplateOutlet="companyLogoTemplate"></ng-container>
</div>

<ng-template #companyLogoTemplate>
  <div class="companyLogo">
    <img [src]="logoSourceUrl">
    <label>The ACME company, {{employeeCount}} people working for you!</label>
  </div>
</ng-template>

テンプレートとテンプレートアウトレットも、コンポーネントを構成可能にするのに役立ちます。次の例は この記事 から Angular University を引用したものです。

タブコンテナーコンポーネントは、デフォルトのタブヘッダーテンプレートを定義しますが、入力プロパティとして定義されたカスタムテンプレートでオーバーライドできます。次に、適切なテンプレート(デフォルトまたはカスタム)がテンプレートアウトレットを使用してビューに挿入されます。

@Component({
  selector: 'tab-container',
  template: `
    <ng-template #defaultTabButtons>
      <div class="default-tab-buttons">
        ...
      </div>
    </ng-template>
    <ng-container *ngTemplateOutlet="headerTemplate || defaultTabButtons"></ng-container>
    ... rest of tab container component ...
  `
})
export class TabContainerComponent {
    @Input() headerTemplate: TemplateRef<any>; // Custom template provided by parent
}

親コンポーネントで、カスタムタブヘッダーテンプレートを定義し、それをタブコンテナーコンポーネントに渡します。

@Component({
  selector: 'app-root',
  template: `      
    <ng-template #customTabButtons>
      <div class="custom-class">
        <button class="tab-button" (click)="login()">
          {{loginText}}
        </button>
        <button class="tab-button" (click)="signUp()">
          {{signUpText}}
        </button>
      </div>
    </ng-template>
    <tab-container [headerTemplate]="customTabButtons"></tab-container>      
  `
})
export class AppComponent implements OnInit {
  ...
}

this blog post by alligator.io で別の高度な使用例を見ることができます。

1
ConnorsFan

非常に有効な質問があります。単純なifまたはswitchのケースで何かを達成できる場合、*ngTemplateOutletを使用する必要があるのはなぜですか?

独立したコンポーネント

1つの独立したコンポーネントレベルについて考えているので、これらの考えを得ています。つまり、すべてが条件付きであり、テンプレートは同じコンポーネント内にあります。特定の条件に基づいてテンプレートを簡単に選択できます。

ライブラリコンポーネント

動的テンプレート

ライブラリコンポーネントとは、AutocompleterまたはTypeaheadなどの汎用の再利用可能なコンポーネントを意味します。これらのコンポーネントは機能的な部分を提供しますが、開発者は独自のtemplateを選択できます彼らのニーズ。

これが問題です。これらのテンプレートはAutocompleterに存在せず、@ContentChildに由来します。

例:

<ng-autocompleter>
   <ng-template #item let-item>{{item.name}}</ng-template>
<ng-autocompleter>

上記の例では、<ng-template>は開発者の後で定義されており、<ng-autocompleter>の直接の部分ではありません。

テンプレートコンテキスト

高度に構成されたコンポーネントが開発されるときはいつでも、テンプレートコンテキストは非常に重要です。動的テンプレート(html)を取得するだけでは、目的を果たすには不十分です。値をng-templateにバインドする必要があります。 ng-templateはng-autocompleterの一部ではないため、バインドに必要なすべてのデータを含むコンテキストを渡す必要があります。

例:上記の場合、item変数はlet-itemによって宣言されていますが、itemはどこから来たかを示しています。それは、*ngTemplateOutletに与えられたコンテキストによって決まります。

一行の結論今後誰かが宣言するテンプレートを挿入したい場合、* ngIfまたは* ngSwitchではこのケースを処理できません。 *ngTemplateOutletを使用する必要があります。

2
Sunil Singh

* ngTemplateOutletのニュアンスがまだ得られない人のために私が書いた非常に詳細な記事があります:

https://www.freecodecamp.org/news/everything-you-need-to-know-about-ng-template-ng-content-ng-container-and-ngtemplateoutlet-4b7b51223691/

1
patrick.1729