この記事では、コンテンツ投影に ng-content
を使用して、柔軟で再利用可能なコンポーネントを作成する方法を検討します。
ng-content
要素は、外部コンテンツまたは動的コンテンツを挿入するためのプレースホルダーです。親コンポーネントは外部コンテンツを子コンポーネントに渡し、Angular がテンプレートを解析すると、外部コンテンツは ng-content
が表示される子コンポーネント テンプレートに挿入されます。
コンテンツ プロジェクションを使用して、再利用可能なコンポーネントを作成できます。これらのコンポーネントは同様のロジックとレイアウトを備えており、多くの場所で使用できます。一般に、いくつかのパブリックコンポーネントをカプセル化するときによく使用されます。 [関連チュートリアルの推奨事項: "angular チュートリアル"]
ng-content
を使用する必要がある理由を理解するにはコンテンツの投影のために、まず非常に一般的なボタン コンポーネントを作成しましょう。
btn.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'app-btn', templateUrl: './btn.component.html', styleUrls: ['./btn.component.scss'], }) export class BtnComponent { constructor() {} onClick($event: any) { console.log($event); } }
btn.component.html
<button (click)=onClick($event)> Click Me </button>
このコンポーネントでは、ボタンのテキストは常に Click Me
です。別のテキストを渡したい場合は?最も一般的に使用される @Input
デコレータを思い浮かべるかもしれませんが、テキストだけではなく HTML を渡したい場合はどうすればよいでしょうか?現時点では、この記事の主人公である ng-content
を使用する必要があります。
コンテンツ プロジェクションの最も基本的な形式は、シングル スロット コンテンツ プロジェクションです。単一スロット コンテンツの投影とは、コンポーネントを投影できるコンポーネントを作成することを意味します。
単一スロット コンテンツ プロジェクションを使用するコンポーネントを作成するには、上記のコンポーネントにいくつかの簡単な変更を加えるだけです。Click Me
を <ng-content> に置き換えます。 </ng-content>
。
btn.component.html
<button (click)=onClick($event)> <ng-content></ng-content> </button>
btn コンポーネントが使用される場所:
<app-btn>Cancel</app-btn> <app-btn><b>Submit</b></app-btn>
In<app-btn></app-btn>
のコンテンツは btn コンポーネントに渡され、ng-contnet
に表示されます。
上記の btn コンポーネントは非常に単純ですが、実際には ng-content
の方がこれよりも強力です。コンポーネントには複数のスロットを含めることができ、各スロットには、そのスロットにどのコンテンツを入れるかを決定する CSS セレクターを指定できます。このモードは、マルチスロット コンテンツ プロジェクションと呼ばれます。このモードを使用する場合は、投影されたコンテンツを表示する場所を指定する必要があります。これは、ng-content
の select
属性を使用して実行できます。
マルチスロット コンテンツ プロジェクションを使用するコンポーネントを作成するには、次の手順を実行する必要があります:
コンポーネントを作成します。
コンポーネント テンプレートで、投影されたコンテンツを表示する場所に ng-content
要素を追加します。
select
属性を ng-content
要素に追加します。 Angular で使用されるセレクターは、タグ名、属性、CSS クラス、および :not
疑似クラスの任意の組み合わせをサポートします。
より複雑なカード コンポーネントを作成してみましょう。
card.component.html
<div class="card"> <div class="header"> <ng-content select="header"></ng-content> </div> <div class="content"> <ng-content select="content"></ng-content> </div> <div class="footer"> <ng-content select="footer"></ng-content> </div> </div>
カード コンポーネントが使用される場所:
app.component.html
<app-card> <header> <h1>Angular</h1> </header> <content>One framework. Mobile & desktop.</content> <footer><b>Super-powered by Google </b></footer> </app-card> <app-card> <header> <h1 style="color:red;">React</h1> </header> <content>A JavaScript library for building user interfaces</content> <footer><b>Facebook Open Source </b></footer> </app-card>
If in app-ヘッダー、コンテンツ、フッターに属さないコンテンツがカード
にありますか?たとえば、app-card
コンポーネントを次のように使用すると:
app.component.html
<app-card> <header> <h1>Angular</h1> </header> <div>Not match any selector</div> <content>One framework. Mobile & desktop.</content> <footer><b>Super-powered by Google </b></footer> <div>This text will not not be shown</div> </app-card>
、両方の div## がわかるでしょう。 # はページ内にレンダリングされません。この問題を解決するには、コンポーネントに
selector を使用せずに
ng-content タグを追加します。他のスロットに一致しないすべてのコンテンツは、このスロットでレンダリングされます。
<div class="card"> <div class="header"> <ng-content select="header"></ng-content> </div> <div class="content"> <ng-content select="content"></ng-content> </div> <div class="footer"> <ng-content select="footer"></ng-content> </div> <ng-content></ng-content> </div>
ng-container を使用してコンテンツをラップして渡す必要があります。コンポーネント内で。ほとんどの場合、
ngIf や
ngSwitch などの構造ディレクティブを使用する必要があることが原因です。たとえば、ヘッダーは特定の状況下でのみカード コンポーネントに渡されます。
ng-container でラップします。
<app-card> <ng-container> <header> <h1>Angular</h1> </header> </ng-container> <content>One framework. Mobile & desktop.</content> <footer><b>Super-powered by Google </b></footer> </app-card>
ng-container の存在により、ヘッダー部分はレンダリングしたいスロットにレンダリングされず、
ng- にレンダリングされます。 selector.content で。
ngProjectAs 属性を使用できます。
ng-container に追加すると、期待どおりにレンダリングできます。
<app-card> <ng-container ngProjectAs='header'> ... </app-card>
プログラミング教育をご覧ください。 !
以上がAngular がコンテンツ投影に ng-content を使用する方法についての簡単な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。