<ng-container> 与 <template>

Posted

技术标签:

【中文标题】<ng-container> 与 <template>【英文标题】:<ng-container> vs <template> 【发布时间】:2017-01-25 15:34:44 【问题描述】:

ng-container 在official documentation 中被提及,但我仍在尝试了解它的工作原理以及用例是什么。

ngPluralngSwitch 指令中特别提到。

&lt;ng-container&gt; 是否与&lt;template&gt; 做同样的事情,还是取决于是否编写了指令来使用其中之一?

<ng-container *ngPluralCase="'=0'">there is nothing</ng-container>

<template [ngPluralCase]="'=0'">there is nothing</template>

应该是一样的吧?

我们如何选择其中之一?

&lt;ng-container&gt; 如何在自定义指令中使用?

【问题讨论】:

【参考方案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

&lt;ng-container&gt; 救援

Angular&lt;ng-container&gt; 是一个不会影响样式或布局的分组元素,因为 Angular 不会将其放入 DOM。

(...)

&lt;ng-container&gt; 是 Angular 解析器识别的语法元素。它不是指令、组件、类或接口。它更像是 javascript if 块中的花括号:

  if (someCondition) 
     statement1; 
     statement2;
     statement3;
    

如果没有这些大括号,JavaScript 只会在您打算有条件地将它们作为一个块执行时才执行第一条语句。 &lt;ng-container&gt; 满足 Angular 模板中的类似需求。

原答案:

根据this pull request:

&lt;ng-container&gt; 是一个逻辑容器,可用于对节点进行分组,但不会在 DOM 树中呈现为节点。

&lt;ng-container&gt; 呈现为 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>

【讨论】:

这很好。我猜它与&lt;template&gt; 在没有指令的情况下使用时不同。在这种情况下,&lt;template&gt; 只会产生 &lt;!--template bindings=--&gt; 其实&lt;template&gt;&lt;/template&gt;会产生&lt;script&gt;&lt;/script&gt;see this 我的情况并非如此。即使编译过程中有&lt;script&gt;,之后也会被删除,DOM中没有多余的标签。我相信该手册包含已弃用的信息,或者只是错误的。无论如何,感谢您指出 在发布之前,Angular 渲染了&lt;script&gt;&lt;/script&gt;。很长一段时间以来,它一直在渲染类似&lt;!--template bindings=--&gt; 的东西。文档很快就会修复。 文档不再包含解释。我试图找到有关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 就是答案。

【讨论】:

但同样的事情可以用&lt;template [ngIf]...&gt;来实现。问题是这两种方法之间的区别。 哦,我的错,似乎在这里回答***.com/questions/40529537/…他们只是说这只是语法差异【参考方案5】:

在我的情况下,它的行为类似于 &lt;div&gt;&lt;span&gt;,但即使 &lt;span&gt; 会与我的 AngularFlex 样式混淆,但 ng-container 不会。

【讨论】:

以上是关于<ng-container> 与 <template>的主要内容,如果未能解决你的问题,请参考以下文章

ng-container 从下到上显示文本

querySelector似乎没有在ng-container中找到元素

使用ng-template,ng-container和ngTemplateOutlet将输入模板的上下文设置为此

ng2 - ng-container 和 ng-template 标签之间的区别

Angule 动态模版 ngTemplateOutlet 的用法

动态 HTML 元素创建