聊聊angular中进行内容投影的方法
一、 ng-content 进行内容投影@H_777_9@
1.1 ng-content
ng-content 元素是一个用来插入外部或者动态内容的占位符。父组件将外部内容传递给子组件,当 Angular 解析模板时,就会在子组件模板中 ng-content 出现的地方插入外部内容。【相关教程推荐:《angular教程》】
我们可以使用内容投影来创建可重用的组件。这些组件有相似的逻辑和布局,并且可以在许多地方使用。一般我们在封装一些公共组件的时候经常会用到。
1.2 为什么使用内容投影
定义一个 button 组件:
button-component.ts
@Component({
selector: '[appButton]', template: ` span class="icon-seArch">
/span>
`}
)export class AppButtonComponent {
}
这个 button 组件的目的是在按钮内部加一个搜索的图标,我们实际使用如下:
button appButton>
click/button>
我们发现组件只会展示搜索图标, 按钮的文本不会展示,能你会想到最常使用的 @Input 装饰器,但是如果我们不只是想传文本进来,而是传一段 htML 进来呢?此时就会用到 ng-content。
1.3 单插槽内容投影
内容投影的最基本形式是单插槽内容投影。
单插槽内容投影是指创建一个组件,我们可以在其中投影一个组件。
以 button 组件为例,创建一个单槽内容投影:
button-component.ts
@Component({
selector: '[appButton]', template: ` span class="icon-search">
/span>
ng-content>
/ng-content>
`}
)export class AppButtonComponent {
}
实际使用如下:
button appButton>
click/button>
可以发现,现在这个 button 组件的效果是即显示了搜索图标,又显示了按钮的文本(click)。即把 button appButton>
/button>
中间的内容 投影 到了组件的 ng-content>
/ng-content>
位置。
ng-content 元素是一个占位符,它不会创建真正的 DOM 元素。ng-content 的那些自定义属性将被忽略。
1.4 多插槽内容投影
一个组件可以具有多个插槽,每个插槽可以指定一个 CSS 选择器,该选择器会决定将哪些内容放入该插槽。该模式称为多插槽内容投影。使用此模式,我们必须指定希望投影内容出现在的位置。可以通过使用 ng-content 的 select 属性来完成此任务。
- 组件模板含有
多个ng-content标签。 - 为了区分投影的内容可以投影到对应
ng-content 标签,需要使用ng-content标签上的select属性作为识别。 select属性支持标签名、属性、CSS 类和:not 伪类的任意组合。- 不添加
select属性的ng-content标签将作为默认插槽。所有未匹配的投影内容都会投影在该ng-content的位置。
以 button 组件为例,创建一个多槽内容投影:
button-component.ts
@Component({
selector: '[appButton]', template: ` span class="icon-search">
/span>
ng-content select="[shuxing]">
/ng-content>
ng-content select="p">
/ng-content>
ng-content select=".lei">
/ng-content>
`}
)export class AppButtonComponent {
}
实际使用如下:
button appButton>
p>
click/p>
span shuxing>
me/span>
span class="lei">
here/span>
/button>
1.5 ngPRojectAs
在某些情况下,我们需要使用 ng-container 把一些内容包裹起来传递到组件中。大多数情况是因为我们需要使用结构型指令像 ngIf 或者 ngSwITch 等。。
在下面的例子中,我们将 header 包裹在了 ng-container 中。
@Component({
selector: 'app-card', template: ` div class="card">
div class="header">
ng-content select="header">
/ng-content>
/div>
div class="content">
ng-content select="content">
/ng-content>
/div>
div class="footer">
ng-content select="footer">
/ng-content>
/div>
ng-content>
/ng-content>
/div>
`}
)export class AppCardComponent {
}
使用:
app-card>
ng-container>
header>
h1>
Angular/h1>
/header>
/ng-container>
content>
One framework. mobile &
desktop./content>
footer>
b>
SuPEr-powered by GOOGLE /b>
/footer>
/app-card>
由于 ng-container 的存在,header 部分并没有被渲染到我们想要渲染的插槽中,而是渲染到了没有提供任何 selector 的 ng-content 中。
在这种情况下,我们可以使用 ngProjectAs 属性。
在上面的 ng-container 加上这个属性,就可以按照我们的期望来渲染了。
app-card>
ng-container ngProjectAs='header'>
header>
h1>
Angular/h1>
/header>
/ng-container>
content>
One framework. Mobile &
desktop./content>
footer>
b>
Super-powered by Google /b>
/footer>
/app-card>
二、 有条件的内容投影
如果你的元件需要有条件地渲染内容或多次渲染内容,则应配置该元件以接受一个 ng-template 元素,其中包含要有条件渲染的内容。
在这种情况下,不建议使用 ng-content 元素,因为只要元件的使用者提供了内容,即使该元件从未定义 ng-content 元素或该 ng-content 元素位于 ngIf 语句的内部,该内容也总会被初始化。
使用 ng-template 元素,你可以让元件根据你想要的任何条件显式渲染内容,并可以进行多次渲染。在显式渲染 ng-template 元素之前,Angular 不会初始化该元素的内容。
2.1 ng-container
既不是一个组件,也不是一个指令,仅仅是一个特殊的tag而已。 使用 ng-container 渲染所包含的模板内容,不包含自身。
- angular代码片段
div>
ng-container>
p>
My name is wyl./p>
p>
What is you name?/p>
/ng-container>
/div>
- 浏览器调试窗口,可以发现
ng-container>标签消失了,并没有起任何作用
div>
p>
My name is wyl./p>
p>
What is you name?/p>
/div>
- 使用场景,如下,在我们需要
遍历或if 判断时,它可以承担一个载体的作用
ul>
ng-container *ngFor="let item of items">
li>
{
{
item .name}
}
/li>
li>
{
{
item .age}
}
/li>
li>
{
{
item .sex}
}
/li>
/ng-container>
/ul>
另外,ng 中常见错误之一的 for 和 if 不能写在同一标签上(在一个宿主元素上只能应用一个结构型指令),利用 ng-container 标签可以在实现功能的基础上减少层级的嵌套。
2.2 ng-template
先来看下面一段代码
ng-template>
p>
In template, no attributes. /p>
/ng-template>
ng-container>
p>
In ng-container, no attributes. /p>
/ng-container>
浏览器输出结果是:
In ng-container, no attributes.
即 ng-template>
中的内容不会显示。当在上面的模板中添加 ngIf 指令:
ng-template [ngIf]="true">
p>
ngIf with a ng-template./p>
/ng-template>
ng-container *ngIf="true">
p>
ngIf with an ng-container./p>
/ng-container>
浏览器输出结果是:
ngIf with a ng-template.ngIf with an ng-container.
2.3 ng-template 和 ng-container>
的配合使用
ng-container *ngIf="showSearchbread;
else tplSearchEmpty">
暂时搜索不到您要的数据喔/ng-container>
ng-template #tplSearchEmpty>
快快开始获取吧!/ng-template>
2.4 ngTemplateOutlet
插入 ng-template 创建的内嵌视图。 ngTemplateOutlet 是一个结构型指令,接收一个 TemplateRef 类型的值;
div *ngTemplateOutlet="tpl1">
/div>
ng-template #tpl1>
span>
I am span in template {
{
title}
}
/span>
/ng-template>
*ngTemplateOutlet = "templateRefExp;
content: contentExp "
- templateRefExp:
ng-template元素的#ID - contextExp:
可空参数
content是一个对象,这个对象可以包含一个$implicit的key作为默认值, 使用时在模板中用let-key语句进行绑定content的非默认字段需要使用let-templateKey=contentKey语句进行绑定
使用如下:
@Component({
selector: 'ng-template-outlet-example', template: ` ng-container *ngTemplateOutlet="greet">
/ng-container>
hr>
ng-container *ngTemplateOutlet="eng;
context: myContext">
/ng-container>
hr>
ng-container *ngTemplateOutlet="svk;
context: myContext">
/ng-container>
hr>
ng-template #greet>
span>
Hello/span>
/ng-template>
ng-template #eng let-name>
span>
Hello {
{
name}
}
!/span>
/ng-template>
ng-template #svk let-person="localSk">
span>
Ahoj {
{
person}
}
!/span>
/ng-template>
`}
)class NgTemplateOutletExample {
myContext = {
$implicit: 'World', localSk: 'Svet'}
;
}
2.5 利用 ngTemplateOutlet 进行内容投影
@Component({
selector: 'app-card', template: ` div class="card">
div class="header">
ng-container *ngTemplateOutlet="headerTemplate;
context: {
$implicit: title, index: otherDate }
">
/ng-container>
/div>
/div>
`}
)export class AppCardComponent {
@ContentChild('header', {
static: true }
) headerTemplate: TemplateRefany>
;
public title = 'test';
public otherDate = {
auth: 'me', name: 'appCard' }
;
}
使用
app-card>
ng-template #header let-label let-item="otherDate">
h1>
Angular/h1>
{
{
label}
}
(Test) and {
{
otherDate | json}
}
({
auth: 'me', name: 'appCard'}
) /ng-template>
/app-card>
更多编程相关知识,请访问:编程教学!!
以上就是聊聊angular中进行内容投影的方法的详细内容,更多请关注其它相关文章!
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: 聊聊angular中进行内容投影的方法
本文地址: https://pptw.com/jishu/593977.html
