本主题描述如何使用内容投影来创建灵活的可复用组件。
要查看或下载本主题中用到的示例代码,请参见现场演练 / 下载范例 。
内容投影是一种模式,你可以在其中插入或投影要在另一个组件中使用的内容。例如,你可能有一个 Card
组件,它可以接受另一个组件提供的内容。
以下各节介绍了 Angular 中内容投影的常见实现,包括:
内容投影的最基本形式是单插槽内容投影。单插槽内容投影是指创建一个组件,你可以在其中投影一个组件。
要创建使用单插槽内容投影的组件,请执行以下操作:
元素,让你希望投影的内容出现在其中。例如,以下组件使用
元素来显示消息。
import { Component } from '@angular/core';
@Component({
selector: 'app-zippy-basic',
template: `
Single-slot content projection
`
})
export class ZippyBasicComponent {}
有了
元素,该组件的用户现在可以将自己的消息投影到该组件中。例如:
Is content projection cool?
元素是一个占位符,它不会创建真正的 DOM 元素。
的那些自定义属性将被忽略。
一个组件可以具有多个插槽。每个插槽可以指定一个 CSS 选择器,该选择器会决定将哪些内容放入该插槽。该模式称为多插槽内容投影。使用此模式,你必须指定希望投影内容出现在的位置。你可以通过使用
的 select
属性来完成此任务。
要创建使用多插槽内容投影的组件,请执行以下操作:
元素,让你希望投影的内容出现在其中。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
属性的内容将投影到带有 select=[question]
属性的
元素。
Is content projection cool?
Let's learn about content projection!
不带 SELECT 属性的 NG-CONTENT
如果你的组件包含不带
select
属性的
元素,则该实例将接收所有与其他
元素都不匹配的投影组件。
在前面的示例中,只有第二个
元素定义了
select
属性。结果,第一个
就会元素接收投影到组件中的任何其他内容。
如果你的组件需要有条件地渲染内容或多次渲染内容,则应配置该组件以接受一个
元素,其中包含要有条件渲染的内容。
在这种情况下,不建议使用
元素,因为只要组件的使用者提供了内容,即使该组件从未定义
元素或该
元素位于 ngIf
语句的内部,该内容也总会被初始化。
使用
元素,你可以让组件根据你想要的任何条件显式渲染内容,并可以进行多次渲染。在显式渲染
元素之前,Angular 不会初始化该元素的内容。
进行条件内容投影的典型实现。
元素的组件中,使用
元素渲染该模板,例如:
本示例使用 ngTemplateOutlet
指令来渲染给定的
元素,你将在后续步骤中对其进行定义。你可以将 ngTemplateOutlet
指令应用于任何类型的元素。本示例就将该指令分配给了
元素,因为该组件不需要渲染真实的 DOM 元素。
元素包装在另一个元素(例如 div
元素)中,然后应用条件逻辑。
元素中,例如:
It depends on what you do with it.
这个
元素定义了一个组件可以根据其自身逻辑渲染的内容块。组件可以使用 @ContentChild
或 @ContentChildren
装饰器获得对此模板内容的引用(即 TemplateRef
)。前面的示例创建了一个自定义指令 appExampleZippyContent
作为 API,以将
标记为组件内容。借助这个 TemplateRef
,组件可以使用 ngTemplateOutlet
指令或ViewContainerRef.createEmbeddedView()
方法来渲染所引用的内容。
@Directive({
selector: '[appExampleZippyContent]'
})
export class ZippyContentDirective {
constructor(public templateRef: TemplateRef) {}
}
在上一步中,你已添加了具有自定义属性 appExampleZippyDirective
的
元素。这段代码提供了当 Angular 遇到该自定义属性时要使用的逻辑。在这里,该逻辑指示 Angular 实例化这个模板引用。
@ContentChild
获取此投影内容的模板。@ContentChild(ZippyContentDirective) content!: ZippyContentDirective;
在执行此步骤之前,你的应用具有一个组件,它会在满足某些条件时实例化此模板。你还创建了一个指令,该指令能提供对该模板的引用。在最后一步中,@ContentChild
装饰器指示 Angular 实例化指定组件中的模板。
如果是多插槽内容投影,则可以使用
@ContentChildren
获取投影元素的查询列表(QueryList)。
如多插槽内容投影中所述,你通常会使用属性、元素、CSS 类或这三者的某种组合来标识将内容投影到何处。例如,在以下 HTML 模板中,p 标签会使用自定义属性 question
将内容投影到 app-zippy-multislot
组件中。
Is content projection cool?
Let's learn about content projection!
在某些情况下,你可能希望将内容投影为其他元素。例如,你要投影的内容可能是另一个元素的子元素。可以用 ngProjectAs
属性来完成此操作。
例如,考虑以下 HTML 代码段:
Is content projection cool?
本示例使用
属性来模拟将组件投影到更复杂的结构中。
注意!
元素是一个逻辑结构,可用于对其他 DOM 元素进行分组;但是,
本身未在 DOM 树中渲染。
在这个例子中,我们要投影的内容位于另一个元素内。为了按预期方式投影此内容,此模板使用了 ngProjectAs
属性。有了 ngProjectAs
,就可以用 [question]
选择器将整个
元素投影到组件中。
标题名称:创新互联Angular教程:Angular内容投影
当前路径:http://www.shufengxianlan.com/qtweb/news34/447384.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联