這篇文章帶大家聊聊angular中的內容投影,介紹一下使用ng-content進行內容投影的方法,並了解有條件內容投影的實現方法,希望對大家有所幫助!
ng-content
進行內容投影1.1 <span style="font-size: 16px;">ng-content</span>
ng-content
元素是用來插入外部或動態內容的佔位符
。父元件將外部內容
傳遞給子元件,當Angular
解析範本時,就會在子元件範本中ng-content
出現的地方插入外部內容。 【相關教學推薦:《angular教學》】
我們可以使用內容投影來建立可重複使用的元件。這些組件有相似的邏輯和佈局,並且可以在許多地方使用。一般我們在封裝
一些公共元件的時候常常會用到。
1.2 為什麼要使用內容投影
定義一個button 元件:
button-component.ts
@Component({ selector: '[appButton]', template: ` <span class="icon-search"></span> ` }) export class AppButtonComponent {}
這個button 元件的目的是在按鈕內部加上一個搜尋的圖標,我們實際使用如下:
<button appButton>click</button>
我們發現元件只會展示搜尋圖標, 按鈕的文字不會展示,能你會想到最常使用的@Input
裝飾器,但是如果我們不只是想傳文字進來,而是傳一段html
進來呢?此時就會用到 ng-content
。
1.3 單一插槽內容投影
#內容投影的最基本形式是單一插槽內容投影
。
單插槽內容投影是指建立一個元件,我們可以在其中投影一個元件。
以button 元件為例,建立一個單槽內容投影:
button-component.ts
@Component({ selector: '[appButton]', template: ` <span class="icon-search"></span> <ng-content></ng-content> ` }) export class AppButtonComponent {}
實際使用如下:
<button appButton>click</button>
可以發現,現在這個button 元件的效果是即顯示了搜尋圖標,又顯示了按鈕的文字(click)。即把2b4ad80bee79097601321f1e5d22b32765281c5ac262bf6d81768915a4a77ac0
中間的內容投影
到了組件的d553bd28b5bbbbd4b6fb4990edbabbf078e68693bbc3a4be56286441c90e88e6
位置。
ng-content 元素是一個佔位符,它不會創建真正的 DOM 元素。 ng-content 的那些自訂屬性將被忽略。
1.4 多重插槽內容投影
#一個元件可以有多個插槽
,每個插槽可以指定一個CSS 選擇器
,該選擇器會決定要將哪些內容放入該插槽。此模式稱為多插槽內容投影
。使用此模式,我們必須指定希望投影內容出現在的位置
。可以透過使用 ng-content
的 select
屬性來完成此任務。
多個
ng-content
標籤。 ng-content 標籤
,需要使用ng-content
標籤上的select
屬性作為識別。 select
屬性支援標籤名稱
、屬性
、CSS 類別
和 :not 偽類別
的任意組合。 select
屬性的 ng-content
標籤將作為預設插槽
。所有未配對的投影內容都會投影在該 ng-content
的位置。 以button 元件為例,建立一個多槽內容投影:
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 <span style="font-size: 16px;">ngProjectAs</span>
在某些情況下,我們需要使用ng-container
把一些內容包裝起來傳遞到元件中。大多數情況是因為我們需要使用結構型指令像 ngIf
或 ngSwitch
等。 。
在下面的範例中,我們將 header
包裹在了 ng-container
中。
@Component({ selector: 'app-card', 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 {}
使用:
<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
的存在,header
部分並沒有被渲染到我們想要渲染的插槽中,而是渲染到了沒有提供任何selector
的ng-content
中。
在這種情況下,我們可以使用 ngProjectAs
屬性。
在上面的 ng-container
加上這個屬性,就可以按照我們的期望來渲染了。
<app-card> <ng-container ngProjectAs='header'> <header> <h1>Angular</h1> </header> </ng-container> <content>One framework. Mobile & desktop.</content> <footer><b>Super-powered by Google </b></footer> </app-card>
如果你的元件需要有条件地渲染内容或多次渲染内容,则应配置该元件以接受一个 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>
d4a8107efa96305af677e1edd4999c73
标签消失了,并没有起任何作用<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.
即 6efee24582b35a5bc3ecd0628f23f6da
中的内容不会显示。当在上面的模板中添加 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>
和 <span style="font-size: 16px;">d4a8107efa96305af677e1edd4999c73</span>
的配合使用
<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中文網其他相關文章!