Angular directive 之 ng-container、ng-template、NgTemplateOutlet 用法介绍 | 更文挑战第8天

412 阅读3分钟

这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

ng-container

是什么

<ng-container> 是一个不会干扰样式或布局的分组元素,Angular 不会将其放入DOM中。
也可以理解为临时容器元素,DOM 元素渲染之后不存在了。

举个例子

<ng-container> 
    <div>莫莫莫</div> 
</ng-container>

上面写法 DOM 元素会被渲染为

<div>莫莫莫</div> 

有何用途?

  • 当我们想用 ngIf 或者 ngFor 时,但是又不想承载它们的元素被渲染时:
<ng-container *ngIf="show"> 
    莫莫莫
</ng-container>

当 show 为 true 时 DOM 元素渲染为

莫莫莫

和ngFor一起使用

<ng-container *ngFor="let item of ['莫', '莫莫', '莫莫莫']"> 
   <div> {{ item }} </div>
</ng-container>

渲染为

<div> 莫 </div>
<div> 莫莫 </div>
<div> 莫莫莫 </div>
  • 结合ngTemplateOutlet使用(ngTemplateOutlet见下文)
<ng-container
    *ngTemplateOutlet="tplName">
</ng-container>

ng-template

是什么

ng-template是一个模板元素,它里面的内容不会渲染,只有其他代码主动调用读取它,它才会显示出来。 如果只是像下面这样写不会显示出来。

<ng-template>
    <p> 这是一块正经的内容 </p>
</ng-template>

举个例子

<ng-template #tpl> 
    <div>莫莫莫</div> 
</ng-template>

定义模板名称的结构是 # + 模板名,如 #tpl,使用的话直接使用模板名 tpl

有何用途?

一般使用场景是有一段html代码,把它包裹在ng-template中,在其他地方使用。其实也可以理解为组件的简版。
它一般和结构型指令结合使用,如*ngIf, *ngFor, [ngSwitch]或其他自定义指令。

眼见为实

<p *ngIf="isCat; else dogTpl">
    小猫
</p>

<ng-template #dogTpl> 小狗 </ng-template>

变量 isCat 的值是 false,dogTpl是模板名,这时候会渲染模板名称为dogTpl里面的内容, DOM 元素会渲染为

<p>
    小狗
</p>

ngTemplateOutlet

是什么

  • 它是一个指令。
  • 拆开来看:ng-template + outlet,即 模板插座。把模板插入到 ngTemplateOutlet的宿主元素里。

举个例子

<p>一只老鼠</p>
<ng-container *ngTemplateOutlet="catTpl"> </ng-container>
<p>一只老鼠</p>

<ng-template #catTpl>
  <p>一只狸花猫</p>
</ng-template>

DOM 元素渲染为

<p>一只老鼠</p>
<p>一只狸花猫</p>
<p>一只老鼠</p>

有何用途?

可以把一段html代码封装成模板,做成插拔式引入进来或者代码复用。

  • 代码复用

鲁迅先生说过: 在我的后园,可以看见墙外有两株树,一株是枣树,还有一株也是枣树。不理解是啥意思也没关系,咱来仿写一段:

<p>那一夜,我左手<ng-container *ngTemplateOutlet="girlTpl"></ng-container> </p>
<p>右手也<ng-container *ngTemplateOutlet="girlTpl"> </ng-container></p>

<ng-template #girlTpl>
搂着一位身姿妖娆的美女
</ng-template>

渲染成了~

<p>那一夜,我左手搂着一位身姿妖娆的美女</p>
<p>右手也搂着一位身姿妖娆的美女</p>

ngTemplateOutlet 如何往模板传递参数呢?

使用 context ~

context: { $implicit: yourValueX, yourKeyY: yourValueY, yourKeyZ: yourValueZ}

  • context接收一个对象,如{ $implicit: yourValueX}, yourValueX 是 TS 中定义的变量
  • $implicit传递的值 yourValueX 在ng-template中使用let-data接收,这是一个固定写法,其实相当于let-data=data, 变量 data 就是 $implicit冒号后面的数据( yourValueX)。
  • 还可以传递更多的参数,形如{ ..., yourKey: yourValue},它其实是这种形式{ key: 参数}, ng-template中取值形式为let-templatekey=yourKey,yourKey 即为传递过来的参数, templatekey 即为在模板中可以使用的变量名。

眼见为实

ts定义参数变量

girlAge = '18岁';
girlHeight: "175cm";

传递参数

<ng-container
    *ngTemplateOutlet="girlTpl; context: { $implicit: girlAge, girlHeight: girlHeight }">
</ng-container>

<ng-template #girlTpl let-data let-height='girlHeight'>
  <div>只见烟雾中,朦胧看到一位身姿妖娆的美女,大约{{ data }}{{ height }}</div>
</ng-template>

DOM渲染为

<div>只见烟雾中,朦胧看到一位身姿妖娆的美女,大约18175cm</div>

更多用法更新于 github