新聞中心
內(nèi)容投影
本主題描述如何使用內(nèi)容投影來(lái)創(chuàng)建靈活的可復(fù)用組件。

要查看或下載本主題中用到的示例代碼,請(qǐng)參見(jiàn)現(xiàn)場(chǎng)演練 / 下載范例 。
內(nèi)容投影是一種模式,你可以在其中插入或投影要在另一個(gè)組件中使用的內(nèi)容。例如,你可能有一個(gè) ?Card ?組件,它可以接受另一個(gè)組件提供的內(nèi)容。
以下各節(jié)介紹了 Angular 中內(nèi)容投影的常見(jiàn)實(shí)現(xiàn),包括:
- 單插槽內(nèi)容投影。使用這種類(lèi)型的內(nèi)容投影,組件可以從單一來(lái)源接受內(nèi)容。
- 多插槽內(nèi)容投影。在這種情況下,組件可以從多個(gè)來(lái)源接受內(nèi)容。
- 有條件的內(nèi)容投影。使用條件內(nèi)容投影的組件僅在滿(mǎn)足特定條件時(shí)才渲染內(nèi)容。
單插槽內(nèi)容投影
內(nèi)容投影的最基本形式是單插槽內(nèi)容投影。單插槽內(nèi)容投影是指創(chuàng)建一個(gè)組件,你可以在其中投影一個(gè)組件。
要?jiǎng)?chuàng)建使用單插槽內(nèi)容投影的組件,請(qǐng)執(zhí)行以下操作:
- 創(chuàng)建一個(gè)組件。
- 在組件模板中,添加 ?
? 元素,讓你希望投影的內(nèi)容出現(xiàn)在其中。
例如,以下組件使用 ?? 元素來(lái)顯示消息。
import { Component } from '@angular/core';
@Component({
selector: 'app-zippy-basic',
template: `
Single-slot content projection
`
})
export class ZippyBasicComponent {}有了 ?? 元素,該組件的用戶(hù)現(xiàn)在可以將自己的消息投影到該組件中。例如:
Is content projection cool?
?
? 元素是一個(gè)占位符,它不會(huì)創(chuàng)建真正的 DOM 元素。?? 的那些自定義屬性將被忽略。
多插槽內(nèi)容投影
一個(gè)組件可以具有多個(gè)插槽。每個(gè)插槽可以指定一個(gè) CSS 選擇器,該選擇器會(huì)決定將哪些內(nèi)容放入該插槽。該模式稱(chēng)為多插槽內(nèi)容投影。使用此模式,你必須指定希望投影內(nèi)容出現(xiàn)在的位置。你可以通過(guò)使用 ?? 的 ?select ?屬性來(lái)完成此任務(wù)。
要?jiǎng)?chuàng)建使用多插槽內(nèi)容投影的組件,請(qǐng)執(zhí)行以下操作:
- 創(chuàng)建一個(gè)組件。
- 在組件模板中,添加 ?
? 元素,讓你希望投影的內(nèi)容出現(xiàn)在其中。 - 將 ?
select?屬性添加到 ?? 元素。 Angular 使用的選擇器支持標(biāo)簽名、屬性、CSS 類(lèi)和?:not? 偽類(lèi)的任意組合。
例如,以下組件會(huì)使用兩個(gè) ?? 元素。
import { Component } from '@angular/core';
@Component({
selector: 'app-zippy-multislot',
template: `
Multi-slot content projection
Default:
Question:
`
})
export class ZippyMultislotComponent {}
使用 ?question ?屬性的內(nèi)容將投影到帶有 ?select=[question]? 屬性的 ?? 元素。
Is content projection cool?
Let's learn about content projection!
不帶 SELECT 屬性的 NG-CONTENT
如果你的組件包含不帶 ?
select?屬性的 ?
? 元素,則該實(shí)例將接收所有與其他 ?
? 元素都不匹配的投影組件。
在前面的示例中,只有第二個(gè) ?
? 元素定義了 ?
select?屬性。結(jié)果,第一個(gè) ?
? 就會(huì)元素接收投影到組件中的任何其他內(nèi)容。
有條件的內(nèi)容投影
如果你的組件需要有條件地渲染內(nèi)容或多次渲染內(nèi)容,則應(yīng)配置該組件以接受一個(gè) ?? 元素,其中包含要有條件渲染的內(nèi)容。
在這種情況下,不建議使用 ?? 元素,因?yàn)橹灰M件的使用者提供了內(nèi)容,即使該組件從未定義 ?? 元素或該 ?? 元素位于 ?ngIf ?語(yǔ)句的內(nèi)部,該內(nèi)容也總會(huì)被初始化。
使用 ?? 元素,你可以讓組件根據(jù)你想要的任何條件顯式渲染內(nèi)容,并可以進(jìn)行多次渲染。在顯式渲染 ?? 元素之前,Angular 不會(huì)初始化該元素的內(nèi)容。
?? 進(jìn)行條件內(nèi)容投影的典型實(shí)現(xiàn)。
- 創(chuàng)建一個(gè)組件。
- 在接受 ?
? 元素的組件中,使用 ?? 元素渲染該模板,例如: - 將 ?
? 元素包裝在另一個(gè)元素(例如 ?div?元素)中,然后應(yīng)用條件邏輯。 - 在要投影內(nèi)容的模板中,將投影的內(nèi)容包裝在 ?
? 元素中,例如: - 創(chuàng)建一個(gè)屬性型指令,它具有與這個(gè)模板的自定義屬性相匹配的選擇器。在此指令中,注入 TemplateRef 實(shí)例。
- 在你要將內(nèi)容投影到的組件中,使用 ?
@ContentChild? 獲取此投影內(nèi)容的模板。
本示例使用 ?ngTemplateOutlet ?指令來(lái)渲染給定的 ?? 元素,你將在后續(xù)步驟中對(duì)其進(jìn)行定義。你可以將 ?ngTemplateOutlet ?指令應(yīng)用于任何類(lèi)型的元素。本示例就將該指令分配給了 ?? 元素,因?yàn)樵摻M件不需要渲染真實(shí)的 DOM 元素。
It depends on what you do with it.
這個(gè) ?? 元素定義了一個(gè)組件可以根據(jù)其自身邏輯渲染的內(nèi)容塊。組件可以使用 ?@ContentChild? 或 ?@ContentChildren? 裝飾器獲得對(duì)此模板內(nèi)容的引用(即 ?TemplateRef?)。前面的示例創(chuàng)建了一個(gè)自定義指令 ?appExampleZippyContent ?作為 API,以將 ?? 標(biāo)記為組件內(nèi)容。借助這個(gè) ?TemplateRef?,組件可以使用 ?ngTemplateOutlet?指令或?ViewContainerRef.createEmbeddedView()?方法來(lái)渲染所引用的內(nèi)容。
@Directive({
selector: '[appExampleZippyContent]'
})
export class ZippyContentDirective {
constructor(public templateRef: TemplateRef) {}
} 在上一步中,你已添加了具有自定義屬性 ?appExampleZippyDirective ?的 ?? 元素。這段代碼提供了當(dāng) Angular 遇到該自定義屬性時(shí)要使用的邏輯。在這里,該邏輯指示 Angular 實(shí)例化這個(gè)模板引用。
@ContentChild(ZippyContentDirective) content!: ZippyContentDirective;在執(zhí)行此步驟之前,你的應(yīng)用具有一個(gè)組件,它會(huì)在滿(mǎn)足某些條件時(shí)實(shí)例化此模板。你還創(chuàng)建了一個(gè)指令,該指令能提供對(duì)該模板的引用。在最后一步中,?@ContentChild? 裝飾器指示 Angular 實(shí)例化指定組件中的模板。
如果是多插槽內(nèi)容投影,則可以使用 ?
@ContentChildren? 獲取投影元素的查詢(xún)列表(QueryList)。
在更復(fù)雜的環(huán)境中投影內(nèi)容
如多插槽內(nèi)容投影中所述,你通常會(huì)使用屬性、元素、CSS 類(lèi)或這三者的某種組合來(lái)標(biāo)識(shí)將內(nèi)容投影到何處。例如,在以下 HTML 模板中,p 標(biāo)簽會(huì)使用自定義屬性 ?question ?將內(nèi)容投影到 ?app-zippy-multislot? 組件中。
Is content projection cool?
Let's learn about content projection!
在某些情況下,你可能希望將內(nèi)容投影為其他元素。例如,你要投影的內(nèi)容可能是另一個(gè)元素的子元素??梢杂?nbsp;?ngProjectAs ?屬性來(lái)完成此操作。
例如,考慮以下 HTML 代碼段:
Is content projection cool?
本示例使用 ?? 屬性來(lái)模擬將組件投影到更復(fù)雜的結(jié)構(gòu)中。
注意!
?
? 元素是一個(gè)邏輯結(jié)構(gòu),可用于對(duì)其他 DOM 元素進(jìn)行分組;但是,?
? 本身未在 DOM 樹(shù)中渲染。
在這個(gè)例子中,我們要投影的內(nèi)容位于另一個(gè)元素內(nèi)。為了按預(yù)期方式投影此內(nèi)容,此模板使用了 ?ngProjectAs ?屬性。有了 ?ngProjectAs?,就可以用 ?[question]? 選擇器將整個(gè) ?? 元素投影到組件中。
網(wǎng)頁(yè)題目:創(chuàng)新互聯(lián)Angular教程:Angular內(nèi)容投影
URL地址:http://m.fisionsoft.com.cn/article/cdoepdh.html


咨詢(xún)
建站咨詢(xún)
