*ngTemplateOutlet
ディレクティブについて読んでいました。このディレクティブの使用は、テンプレート参照とコンテキストオブジェクトをパラメーターとして動的にテンプレートをインスタンス化することです。
私が知りたいのは、Angularには次のような* ngTemplateOutletと同じ結果を達成するために非常に多くのものが含まれているということです。
同じコンポーネント内のコンポーネント変数値に基づいて異なるテンプレートをレンダリングできる複数の*ngIf
を使用できます。同様に、[ngSwitch]
があり、異なる値に基づいて異なるテンプレートがレンダリングされます。
それぞれの変数のテンプレート参照変数を参照することにより、*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
ディレクティブを使用する必要がある実際の使用例(ある場合)は何ですか?それとも同じ結果を達成するために選択する別の方法ですか?
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 で別の高度な使用例を見ることができます。
非常に有効な質問があります。単純な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
を使用する必要があります。
* ngTemplateOutletのニュアンスがまだ得られない人のために私が書いた非常に詳細な記事があります: