如果你尝试在 Angular 中编写可重复使用的组件,则可能会接触到内容投射的概念。然后你发现了 <ng-content>
,并找到了一些关于它的文章,进而实现了所需的功能。
接下来我们来通过一个简单的示例,一步步介绍 <ng-content>
所涉及的内容。
Simple example
在本文中我们使用一个示例,来演示不同的方式实现内容投影。由于许多问题与Angular 中的组件生命周期相关,因此我们的主要组件将显示一个计数器,用于展示它已被实例化的次数:
import { Component } from '@angular/core';let instances = 0;@Component({ selector: 'counter', template: '<h1>{{this.id}}</h1>'})class Counter { id: number; constructor() { this.id = ++instances; }}
上面示例中我们定义了 Counter 组件,组件类中的 id 属性用于显示本组件被实例化的次数。接着我们继续定义一个 Wrapper 组件:
import { Component } from '@angular/core';@Component({ selector: 'wrapper', template: ` <div class="box"> <ng-content></ng-content> </div> `})class Wrapper {}
现在我们来验证一下效果:
<wrapper> <counter></counter> <counter></counter> <counter></counter></wrapper>
Targeted projection
有时你希望将包装器的不同子项投影到模板的不同部分。为了处理这个问题, <ng-content>
支持一个 select
属性,可以让你在特定的地方投射具体的内容。该属性支持 CSS 选择器(my-element,.my-class,[my-attribute],...)来匹配你想要的内容。如果 ng-content
上没有设置 select
属性,它将接收全部内容,或接收不匹配任何其他 ng-content 元素的内容。长话短说:
import { Component } from '@angular/core';@Component({ selector: 'wrapper', template: ` <div class="box red"> <ng-content></ng-content> </div> <div class="box blue"> <ng-content select="counter"></ng-content> </div> `, styles: [` .red {background: red;} .blue {background: blue;} `]})export class Wrapper { }
上面示例中,我们引入了 select
属性,来选择投射的内容:
<wrapper> <span>This is not a counter</span> <counter></counter></wrapper>
上述代码成功运行后,counter
组件被正确投影到第二个蓝色框中,而 span 元素最终会在全部红色框中。请注意,目标 ng-content
会优先于 catch-all,即使它在模板中的位置靠后。
ngProjectAs
有时你的内部组件会被隐藏在另一个更大的组件中。有时你只需要将其包装在额外的容器中即可应用
新闻热点
疑难解答
图片精选