qrcode

马上订阅,开启修仙之旅

Angular ng-template vs ng-container

通常情况下,当我们使用结构指令时,我们需要添加额外的标签来封装内容,如使用 *ngIf 指令:

1
2
3
4
5
6
7
8
<section *ngIf="show">
<div>
<h2>Div one</h2>
</div>
<div>
<h2>Div two</h2>
</div>
</section>

上面示例中,我们在 section 标签上应用了 ngIf 指令,从而实现 section 标签内容的动态显示。这种方式有个问题是,我们必须添加额外的 DOM 元素。要解决该问题,我们可以使用 <ng-template> 的标准语法 (非*ngIf 语法糖):

1
2
3
4
5
6
7
8
<ng-template [ngIf]="show">
<div>
<h2>Div one</h2>
</div>
<div>
<h2>Div two</h2>
</div>
</ng-template>

问题是解决了但我们不再使用 * 语法糖语法,这样会导致我们代码的不统一。虽然解决了问题,但又带来了新问题。那我们还有其它的方案么?答案是有的,我们可以使用 ng-container 指令。

ng-container

<ng-container> 是一个逻辑容器,可用于对节点进行分组,它将被渲染为 HTML中的 comment 元素。具体示例如下:

1
2
3
4
5
6
7
8
<ng-container *ngIf="show">
<div>
<h2>Div one</h2>
</div>
<div>
<h2>Div two</h2>
</div>
</ng-container>

有时我们需要根据 switch 语句,动态显示文本,这时我们需要添加一个额外的标签如 <span> ,比如:

1
2
3
4
<div [ngSwitch]="value">
<span *ngSwitchCase="0">Text one</span>
<span *ngSwitchCase="1">Text two</span>
</div>

针对这种情况,理论上我们是不需要添加额外的 <span> 标签,这时我们可以使用 ng-container 来解决这个问题:

1
2
3
4
<div [ngSwitch]="value">
<ng-container *ngSwitchCase="0">Text one</ng-container>
<ng-container *ngSwitchCase="1">Text two</ng-container>
</div>

此外 Angular 的初学者,可能会在某个标签上同时使用 *ngIf*ngFor 指令,比如:

1
2
3
4
5
<div class="lesson" *ngIf="lessons" *ngFor="let lesson of lessons">
<div class="lesson-detail">
{{lesson | json}}
</div>
</div>

当以上代码运行后,你将会看到以下报错信息:

1
2
3
Uncaught Error: Template parse errors:
Can't have multiple template bindings on one element. Use only one attribute
named 'template' or prefixed with *

这意味着不可能将两个结构指令应用于同一个元素。要解决这个问题,我可以就利用 ng-container

1
2
3
4
5
6
7
<ng-container *ngIf="lessons">
<div class="lesson" *ngFor="let lesson of lessons">
<div class="lesson-detail">
{{lesson | json}}
</div>
</div>
</ng-container>

ng-template vs ng-container

介绍完 ng-container 指令,我们来分析一下它跟 ng-template 指令有什么区别?我们先看以下示例:

1
2
3
4
5
6
7
<ng-template>
<p> In template, no attributes. </p>
</ng-template>

<ng-container>
<p> In ng-container, no attributes. </p>
</ng-container>

以上代码运行后,浏览器中输出结果是:

1
In ng-container, no attributes.

<ng-template> 中的内容不会显示。当在上面的模板中应用 ngIf 指令:

1
2
3
4
5
6
7
<ng-template [ngIf]="true">
<p> ngIf with a template.</p>
</ng-template>

<ng-container *ngIf="true">
<p> ngIf with an ng-container.</p>
</ng-container>

以上代码运行后,浏览器中输出结果是:

1
2
ngIf with a template.
ngIf with an ng-container.

最后我们来总结一下 <ng-template><ng-container> 的区别:

  • <ng-template> :使用 * 语法糖的结构指令,最终都会转换为 <ng-template><template> 模板指令,模板内的内容如果不进行处理,是不会在页面中显示的。
  • <ng-container>:是一个逻辑容器,可用于对节点进行分组,它将被渲染为 HTML中的 comment 元素,它可用于避免添加额外的元素来使用结构指令。

欢迎小伙伴们订阅前端修仙之路,及时阅读 Angular、RxJS、TypeScript 和 Node.js 最新文章。

qrcode