内容投影
内容投影就是将 angular 组件包裹的 html 插入到组件模版的某个位置
单插槽的内容投影
组件从单一来源接收内容
import { Component } from "@angular/core";
@Component({
selector: "app-zippy-basic",
template: `
<h2>Single-slot content projection</h2>
<ng-content></ng-content>
`
})
export class ZippyBasicComponent {}
<app-zippy-basic>
<p>Is content projection cool?</p>
</app-zippy-basic>
<ng-content>
元素是一个占位符,它不会创建真正的 DOM 元素。<ng-content>
的那些自定义属性将被忽略。
多插槽的内容投影
组件从多个来源接收内容
一个组件可以具有多个插槽。每个插槽可以指定一个 CSS 选择器,该选择器会决定将哪些内容放入该插槽。可以给 ng-content 组件上添加 select 属性来实现这个功能 select 属性的值是一个 css 选择器
import { Component } from "@angular/core";
@Component({
selector: "app-zippy-multislot",
template: `
<h2>Multi-slot content projection</h2>
Default:
<ng-content></ng-content>
Question:
<ng-content select="[question]"></ng-content>
`
})
export class ZippyMultislotComponent {}
使用 question 属性的内容将投影到带有 select=[question]
属性的 <ng-content>
元素。
<app-zippy-multislot>
<p question>
Is content projection cool?
</p>
<p>Let's learn about content projection!</p>
</app-zippy-multislot>
不带 SELECT 属性的 NG-CONTENT
如果你的组件包含不带 select 属性的 <ng-content>
元素,则该实例将接收所有与其他 <ng-content>
元素都不匹配的投影组件。
在前面的示例中,只有第二个 <ng-content>
元素定义了 select 属性。结果,第一个 <ng-content>
就会元素接收投影到组件中的任何其他内容。
有条件的内容投影
使用 ng-template 来实现
在这种情况下,不建议使用 ng-content 元素,因为只要组件的使用者提供了内容,即使该组件从未定义 ng-content 元素或该 ng-content 元素位于 *ngIf 语句的内部,该内容也总会被初始化。
ngProjectAs
在某些情况下,你可能希望将内容投影为其他元素。例如,你要投影的内容可能是另一个元素的子元素。可以用 ngProjectAs(值也是一个 CSS 选择器) 属性来完成此操作。
<ng-container ngProjectAs="[question]">
<p>Is content projection cool?</p>
</ng-container>
这个 ng-container 元素中的内容也会被投影到组件的 ng-content && select='[question]' 中