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

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


咨詢
建站咨詢
