この記事では、angular でのコンテンツ投影について説明し、コンテンツ投影に ng-content を使用する方法を紹介し、条件付きコンテンツ投影の実装方法を理解します。 !
ng-content
コンテンツ投影1.1 <span style="font-size: 16px;">ng-content</span>
ng-content
要素は、外部または動的コンテンツ シンボルを挿入するために使用される プレースホルダーです## #。親コンポーネントは、
外部コンテンツを子コンポーネントに渡します。
Angularがテンプレートを解析すると、外部コンテンツは子コンポーネントのテンプレートに挿入されます。と表示されます。 [関連チュートリアルの推奨事項: "
angular チュートリアル"]
コンテンツ プロジェクションを使用して、再利用可能なコンポーネントを作成できます。これらのコンポーネントは同様のロジックとレイアウトを備えており、多くの場所で使用できます。一般に、いくつかのパブリック コンポーネントを カプセル化する場合によく使用されます。
1.2 コンテンツ プロジェクションを使用する理由
ボタン コンポーネントを定義します:
button-component.ts@Component({ selector: '[appButton]', template: ` <span class="icon-search"></span> ` }) export class AppButtonComponent {}
このボタン コンポーネントの目的は、ボタン内に検索アイコンを追加することです。実際には次のように使用します: <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;"><button appButton>click</button></pre><div class="contentsignin">ログイン後にコピー</div></div><div class="contentsignin">ログイン後にコピー</div></div>
コンポーネントは検索アイコンのみを表示することがわかりました。ボタンのテキストは表示されません。最も一般的に使用される
デコレータを思い浮かべるかもしれませんが、テキストだけでなく ## の段落を渡したい場合はどうなるでしょうか。 #html
?現時点ではng-content が使用されます。
1.3 シングル スロット コンテンツ プロジェクション
コンテンツ プロジェクションの最も基本的な形式は、シングル スロット コンテンツ プロジェクションです。
単一スロット コンテンツの投影とは、コンポーネントを投影できるコンポーネントを作成することを指します。
button-component.ts
@Component({ selector: '[appButton]', template: ` <span class="icon-search"></span> <ng-content></ng-content> ` }) export class AppButtonComponent {}
<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;"><button appButton>click</button></pre><div class="contentsignin">ログイン後にコピー</div></div><div class="contentsignin">ログイン後にコピー</div></div> このボタン コンポーネントの効果は、検索アイコンとボタン (クリック) のテキストの両方を表示することであることがわかります。つまり、
は、
ng-content 要素はプレースホルダーであり、実際の DOM 要素を作成するものではありません。 ng-content のカスタム属性は無視されます。
1.4 マルチスロット コンテンツ プロジェクションコンポーネントは
複数のスロット を持つことができ、各 A スロットはCSS セレクター を指定します。これにより、スロットに入るコンテンツが決定されます。このモードは、マルチスロット コンテンツ プロジェクション
と呼ばれます。このモードを使用すると、投影されたコンテンツ を表示する位置 を指定する必要があります。これは、
ng-content の
select 属性を使用して実行できます。
コンポーネント テンプレートには、
複数の
タグが含まれています。
に投影できる投影されたコンテンツを区別するには、
ng の select
属性を使用する必要があります。 -content
select 属性は、
tag name、
property、
:not pseudo-class# をサポートします。 # # の任意の組み合わせ。 select
属性を追加しない ng-content
タグは、default スロット
として機能します。一致しない投影されたコンテンツはすべて、この ng-content
の場所に投影されます。 ボタン コンポーネントを例として、マルチスロット コンテンツ プロジェクションを作成します:
button-component.ts
@Component({ selector: '[appButton]', template: ` <span class="icon-search"></span> <ng-content select="[shuxing]"></ng-content> <ng-content select="p"></ng-content> <ng-content select=".lei"></ng-content> ` }) export class AppButtonComponent {}
実際の使用法は次のとおりです。
<button appButton> <p>click</p> <span shuxing>me</span> <span class="lei">here</span> </button>
1.5
ngProjectAs
場合によっては、 ng-container を使用する必要があります。コンテンツをラップしてコンポーネントに渡します。ほとんどの場合、ngIf や <span style="font-size: 16px;">ngSwitch</span> などの構造ディレクティブを使用する必要があることが原因です。 。
以下の例では、
を ng-container
でラップしています。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">@Component({
selector: &#39;app-card&#39;,
template: `
<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>
`
})
export class AppCardComponent {}</pre><div class="contentsignin">ログイン後にコピー</div></div>
使用法: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;"><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></pre><div class="contentsignin">ログイン後にコピー</div></div>
が存在するため、header
部分はレンダリングしたいスロットにレンダリングされません. の代わりに、selector
を提供しない
にレンダリングされます。
この場合、ngProjectAs 属性を使用できます。
この属性を上記の ng-container
に追加すると、期待どおりにレンダリングできます。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;"><app-card>
<ng-container ngProjectAs=&#39;header&#39;>
<header>
<h1>Angular</h1>
</header>
</ng-container>
<content>One framework. Mobile & desktop.</content>
<footer><b>Super-powered by Google </b></footer>
</app-card></pre><div class="contentsignin">ログイン後にコピー</div></div><h2><strong>二、 有条件的内容投影</strong></h2><p>如果你的元件需要有条件地渲染内容或多次渲染内容,则应配置该元件以接受一个 <code>ng-template
元素,其中包含要有条件渲染的内容。
在这种情况下,不建议使用 ng-content
元素,因为只要元件的使用者提供了内容,即使该元件从未定义 ng-content
元素或该 ng-content
元素位于 ngIf
语句的内部,该内容也总会被初始化。
使用 ng-template
元素,你可以让元件根据你想要的任何条件显式渲染内容,并可以进行多次渲染。在显式渲染 ng-template
元素之前,Angular
不会初始化
该元素的内容。
2.1 <span style="font-size: 16px;">ng-container</span>
既不是一个组件,也不是一个指令,仅仅是一个特殊的tag而已。 使用 ng-container
渲染所包含的模板内容,不包含自身。
<div> <ng-container> <p>My name is wyl.</p> <p>What is you name?</p> </ng-container> </div>
<ng-container>
标签消失了,并没有起任何作用<div> <p>My name is wyl.</p> <p>What is you name?</p> </div>
遍历
或 if 判断
时,它可以承担一个载体
的作用<ul> <ng-container *ngFor="let item of items"> <li>{{ item .name}}</li> <li>{{ item .age}}</li> <li>{{ item .sex}}</li> </ng-container> </ul>
另外,ng
中常见错误之一的 for
和 if
不能写在同一标签上(在一个宿主元素上只能应用一个结构型指令),利用 ng-container
标签可以在实现功能的基础上减少层级的嵌套。
2.2 <span style="font-size: 16px;">ng-template</span>
先来看下面一段代码
<ng-template> <p> In template, no attributes. </p> </ng-template> <ng-container> <p> In ng-container, no attributes. </p> </ng-container>
浏览器输出结果是:
In ng-container, no attributes.
即 <ng-template>
中的内容不会显示。当在上面的模板中添加 ngIf
指令:
<ng-template [ngIf]="true"> <p> ngIf with a ng-template.</p> </ng-template> <ng-container *ngIf="true"> <p> ngIf with an ng-container.</p> </ng-container>
浏览器输出结果是:
ngIf with a ng-template. ngIf with an ng-container.
2.3 <span style="font-size: 16px;">ng-template</span>
和 <ng-container>
的配合使用
<ng-container *ngIf="showSearchBread; else tplSearchEmpty"> 暂时搜索不到您要的数据喔 </ng-container> <ng-template #tplSearchEmpty> 快快开始获取吧! </ng-template>
2.4 <span style="font-size: 16px;">ngTemplateOutlet</span>
插入 ng-template
创建的内嵌视图。 ngTemplateOutlet
是一个结构型指令
,接收一个 TemplateRef
类型的值;
<div *ngTemplateOutlet="tpl1"></div> <ng-template #tpl1> <span>I am span in template {{title}}</span> </ng-template>
*ngTemplateOutlet = "templateRefExp; content: contentExp "
ng-template
元素的 #ID
可空参数
content
是一个对象,这个对象可以包含一个 $implicit
的 key
作为默认值, 使用时在 模板
中用 let-key
语句进行绑定
content
的非默认字段需要使用 let-templateKey=contentKey
语句进行绑定
使用如下:
@Component({ selector: 'ng-template-outlet-example', template: ` <ng-container *ngTemplateOutlet="greet"></ng-container> <hr> <ng-container *ngTemplateOutlet="eng; context: myContext"></ng-container> <hr> <ng-container *ngTemplateOutlet="svk; context: myContext"></ng-container> <hr> <ng-template #greet><span>Hello</span></ng-template> <ng-template #eng let-name><span>Hello {{name}}!</span></ng-template> <ng-template #svk let-person="localSk"><span>Ahoj {{person}}!</span></ng-template> ` }) class NgTemplateOutletExample { myContext = {$implicit: 'World', localSk: 'Svet'}; }
2.5 利用 <span style="font-size: 16px;">ngTemplateOutlet</span>
进行内容投影
@Component({ selector: 'app-card', template: ` <div class="card"> <div class="header"> <ng-container *ngTemplateOutlet="headerTemplate; context: { $implicit: title, index: otherDate }"></ng-container> </div> </div> ` }) export class AppCardComponent { @ContentChild('header', { static: true }) headerTemplate: TemplateRef<any>; public title = 'Test'; public otherDate = { auth: 'me', name: 'appCard' }; }
使用
<app-card> <ng-template #header let-label let-item="otherDate"> <h1>Angular</h1> {{label}} (Test) and {{otherDate | json}} ({auth: 'me', name: 'appCard'}) </ng-template> </app-card>
更多编程相关知识,请访问:编程教学!!
以上がAngular でのコンテンツ投影の方法について話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。