<ng-container> 与 <template>
Posted
技术标签:
【中文标题】<ng-container> 与 <template>【英文标题】:<ng-container> vs <template> 【发布时间】:2017-01-25 15:34:44 【问题描述】:ng-container
在official documentation 中被提及,但我仍在尝试了解它的工作原理以及用例是什么。
在ngPlural
和ngSwitch
指令中特别提到。
<ng-container>
是否与<template>
做同样的事情,还是取决于是否编写了指令来使用其中之一?
是
<ng-container *ngPluralCase="'=0'">there is nothing</ng-container>
和
<template [ngPluralCase]="'=0'">there is nothing</template>
应该是一样的吧?
我们如何选择其中之一?
<ng-container>
如何在自定义指令中使用?
【问题讨论】:
【参考方案1】:ng-container
的 Imo 用例是简单的替换,自定义模板/组件可能会过度使用。在 API 文档中,他们提到了以下内容
使用 ng-container 对多个根节点进行分组
我猜这就是它的全部意义:分组。
请注意,ng-container
指令会消失,而不是其指令包装实际内容的模板。
【讨论】:
你有这个提及的链接吗?目前仅在上述链接文档和复数案例文档中看到它:angular.io/docs/ts/latest/api/common/index/…。 angular.io/docs/ts/latest/api/common/index/… 谢谢,在文档站点上创建了一个关于缺乏文档的问题并引用了这个答案:github.com/angular/angular.io/issues/2553 投反对票 -1。 ng-container 不是要避免使用自定义模板,而是要能够拥有未包装在容器中的条件内容。实际上自定义模板也会引入一个包装容器,即指令标签本身。 你是绝对正确的。这肯定是需要提及的差异。我已将提示添加到我的帖子中。【参考方案2】:编辑:现在是documented
<ng-container>
救援Angular
<ng-container>
是一个不会影响样式或布局的分组元素,因为 Angular 不会将其放入 DOM。(...)
<ng-container>
是 Angular 解析器识别的语法元素。它不是指令、组件、类或接口。它更像是 javascript if 块中的花括号:if (someCondition) statement1; statement2; statement3;
如果没有这些大括号,JavaScript 只会在您打算有条件地将它们作为一个块执行时才执行第一条语句。
<ng-container>
满足 Angular 模板中的类似需求。
原答案:
根据this pull request:
<ng-container>
是一个逻辑容器,可用于对节点进行分组,但不会在 DOM 树中呈现为节点。
<ng-container>
呈现为 html 注释。
所以这个角度模板:
<div>
<ng-container>foo</ng-container>
<div>
会产生这种输出:
<div>
<!--template bindings=-->foo
<div>
所以ng-container
在您想在应用程序中有条件地附加一组元素(即使用*ngIf="foo"
)但不想用另一个元素包装它们时很有用。。 p>
<div>
<ng-container *ngIf="true">
<h2>Title</h2>
<div>Content</div>
</ng-container>
</div>
然后会产生:
<div>
<h2>Title</h2>
<div>Content</div>
</div>
【讨论】:
这很好。我猜它与<template>
在没有指令的情况下使用时不同。在这种情况下,<template>
只会产生 <!--template bindings=-->
。
其实<template></template>
会产生<script></script>
see this
我的情况并非如此。即使编译过程中有<script>
,之后也会被删除,DOM中没有多余的标签。我相信该手册包含已弃用的信息,或者只是错误的。无论如何,感谢您指出 <script></script>
。很长一段时间以来,它一直在渲染类似<!--template bindings=-->
的东西。文档很快就会修复。
文档不再包含解释。我试图找到有关ng-container
的文档页面,但没有找到任何内容。它是否已被弃用,为什么没有记录?【参考方案3】:
文档 (https://angular.io/guide/template-syntax#!#star-template) 给出了以下示例。假设我们有这样的模板代码:
<hero-detail *ngIf="currentHero" [hero]="currentHero"></hero-detail>
在渲染之前,它会被“脱糖”。即星号符号将被转录为符号:
<template [ngIf]="currentHero">
<hero-detail [hero]="currentHero"></hero-detail>
</template>
如果 'currentHero' 是真实的,这将呈现为
<hero-detail> [...] </hero-detail>
但是如果你想要这样的条件输出怎么办:
<h1>Title</h1><br>
<p>text</p>
.. 并且您不希望将输出包装在容器中。
您可以像这样直接编写脱糖版本:
<template [ngIf]="showContent">
<h1>Title</h1>
<p>text</p><br>
</template>
这会很好。但是,现在我们需要 ngIf 有括号 [] 而不是星号 *,这很令人困惑 (https://github.com/angular/angular.io/issues/2303)
因此创建了不同的符号,如下所示:
<ng-container *ngIf="showContent"><br>
<h1>Title</h1><br>
<p>text</p><br>
</ng-container>
两个版本都会产生相同的结果(只有 h1 和 p 标签会被渲染)。第二个是首选,因为您可以像往常一样使用 *ngIf。
【讨论】:
很好的解释,它提供了ng-container
指令的想法是如何来的概述,谢谢 :)【参考方案4】:
当您想使用带有 *ngIf 和 *ngFor 的表格时的一个用例 - 因为将 div 放入 td/th 会使表格元素行为不端 -。我遇到了这个问题,that 就是答案。
【讨论】:
但同样的事情可以用<template [ngIf]...>
来实现。问题是这两种方法之间的区别。
哦,我的错,似乎在这里回答***.com/questions/40529537/…他们只是说这只是语法差异【参考方案5】:
在我的情况下,它的行为类似于 <div>
或 <span>
,但即使 <span>
会与我的 AngularFlex 样式混淆,但 ng-container
不会。
【讨论】:
以上是关于<ng-container> 与 <template>的主要内容,如果未能解决你的问题,请参考以下文章
querySelector似乎没有在ng-container中找到元素
使用ng-template,ng-container和ngTemplateOutlet将输入模板的上下文设置为此
ng2 - ng-container 和 ng-template 标签之间的区别