Angular2+ ng-content用法

Angular2+中的的内容映射使用的是ng-content指令,内容映射指的是在组件中嵌入模板代码,方便定制可复用的组件。下面用例子来解释一下ng-content的用法:

app.component.ts

<parent-content>
  <child-content></child-content>
</parent-content>

可以把被包含的组件称为子组件,外层称为父组件。我们看下父组件怎么写的:
parent-content.component.ts

import {Component, OnInit} from '@angular/core'

@Component({
  selector: 'parent-content',
  template: `
    <h1>this is parent-content</h1>
    <ng-content></ng-content>
  `,
  styleUrls: ['./parent-content.component.less']
})
export class ParentContentComponent implements OnInit {
  constructor() {
  }
  ngOnInit(): void {
  }
}

再看下子组件是怎么写的:
child-content.component.ts

@Component({
 selector: 'child-content',
 template: `<p>this is child-content</p>`,
})

这样子组件child-content.component.ts的内容就会映射到parent-content.component.tsng-content中去,此时,如果我们想访问或者操作子组件中的方法或属性,可以通过下面的方式去访问:
@ContentChild(childComponent) child
它和@ViewChild非常类似,就不多做介绍了,其异同点列举如下:

相同点

  • 都是属性装饰器
  • 都有对应的复数形式装饰器:ContentChildren、ViewChildren
  • 都支持 Type|Function|string 类型的选择器

不同点

  • ContentChild 用来从通过 Content Projection 方式 (ng-content) 设置的视图中获取匹配的元素
  • ViewChild 用来从模板视图中获取匹配的元素
  • 在父组件的 ngAfterContentInit 生命周期钩子中才能成功获取通过 ContentChild 查询的元素
  • 在父组件的 ngAfterViewInit 生命周期钩子中才能成功获取通过 ViewChild 查询的元素

另外:ng-content还有一个 select 属性,主要作用是能够选择行的选择要映射的组件,但是可供选择的组件必须包含在父组件内部,这里的选择有三种选择方式,分别是:属性、标签、CSS,下面咱们看下具体的使用方法:

  1. 属性选择

parent.component.html

<div style="border:1px solid red">
      <ng-content select=".red"></ng-content>
    </div>
    <div style="border:1px solid blue;margin-top:10px">
      <ng-content select="[name=child]"></ng-content>
    </div>
    <div style="border:1px solid #ffdd3f;margin-top:10px">
      <ng-content select="[first]"></ng-content>
    </div>

app.component.html

<parent-content>
  <child-content first></child-content>
  <child-content second></child-content>
</parent-content>

这里选择映射的就是具有first属性的子组件

  1. 标签选择
<ng-content select="child-content1"></ng-content>

< ng-content select= “child-content1” ></ ng-content >

再看下父组件内部:

<parent-content>
  <child-content1></child-content1>
  <child-content2></child-content2>
</parent-content>

这里选择映射的就是标签名称为"child-content1"的子组件
3.CSS选择

<ng-content select=".myChild"></ng-content>

再看下父组件内部:

<parent-content>
  <child-content1 class="myChild"></child-content1>
  <child-content2></child-content2>
</parent-content>

这里选择映射的就是类名为"myChild"的子组件
注意:select 的值不能设置成动态的,动态的值会导致无法正常映射组件.

说到这里,不得不说一下一个属性ngProjectAs,这个属性是用来干什么的呢?我们来看一下:

我们将子组件包装在这个容器中,并使用select属性进行选择映射,运行程序后看下结果:

parent.component.ts

<div style="border:1px solid red">
  <ng-content></ng-content>
</div>
<div style="border:1px solid blue;margin-top:10px">
  <ng-content select="child-content"></ng-content>
</div>

app.component.ts

<parent-content>
  <ng-container>
    <child-content></child-content>
  </ng-container>
</parent-content>

效果:
效果1
此时我们发现,子组件只映射到了红色的div中,蓝色div中的子组件并没有映射出来,这是因为<ng-container>不在匹配select=“child-content”,这里说下<ng-container>,这只是一个特殊的标签,有点类似于template,Angular复用了HTML5规范中template 的tag的语义,不过并没有真正利用其实现,因此在审查元素中是永远也找不到一个template元素的。 不过,由于ng-container并不是HTML5中的,为了保持区分度,采用了ng-作为前缀。言归正传,要解决这个问题,就得利用 ngProjectAs 这个属性。

<parent-content>
  <ng-container ngProjectAs="child-content">
    <child-content></child-content>
  </ng-container>
</parent-content>

效果2
此时发现蓝色div中映射了子组件。就解决了这个问题。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值