<ng-container>与<template>


150

ng-container 在Angular 2文档中提到过,但没有解释它如何工作以及用例是什么。

ngPluralngSwitch指令中特别提到了它。

是否与<ng-container>做相同的事情<template>,还是取决于是否编写了使用其中一个指令的指令?

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

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

应该是一样的吗?

我们如何选择其中之一?

如何<ng-container>在自定义指令中使用?

Answers:


244

编辑:现在已记录在案

<ng-container> 营救

Angular  <ng-container> 是一个分组元素,不会干扰样式或布局,因为Angular不会将其放在DOM中。

(...)

的  <ng-container> 是由角分析器识别的语法元素。它不是指令,组件,类或接口。它更像是JavaScript if块中的花括号:

  if (someCondition) {
      statement1; 
      statement2;
      statement3;
     }

没有这些花括号,JavaScript仅在您打算有条件地将它们全部作为一个块执行时才执行第一条语句。在  <ng-container> 满足同样需要在角模板。

原始答案:

根据此拉取要求

<ng-container> 是一个逻辑容器,可用于对节点进行分组,但不能在DOM树中作为节点呈现。

<ng-container> 呈现为HTML注释。

所以这个角度模板:

<div>
    <ng-container>foo</ng-container>
<div>

将产生这种输出:

<div>
    <!--template bindings={}-->foo
<div>

ng-container当您想*ngIf="foo"在应用程序中有条件地追加一组元素(即使用),但又不想用其他元素包装它们时,这很有

<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={}-->
Estus Flask,

实际上,<template></template>将产生<script></script> 此效果
n00dl3

就我而言并非如此。即使<script>在编译过程中存在,也将其删除,但DOM中没有多余的标签。我认为该手册包含过时的信息,或者只是错误的信息。无论如何,感谢您指出<ng-container>和<template>之间的主要区别。
Estus Flask

发布之前,Angular已渲染<script></script>。它已经渲染了<!--template bindings={}-->一段时间了。该文档将很快修复。
病房”

40

文档(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,谢谢:)
Pankaj Parkar'9

0

Imo用例ng-container是简单的替代品,对于这些替代品,自定义模板/组件可能会过大。他们在API文档中提到了以下内容

使用ng容器将多个根节点分组

我想这就是全部内容:将内容分组。

请注意,该ng-container指令代替了包装实际内容的模板而不是模板。


您是否有此提及的链接?目前仅在上面的链接文档和复数案例文档中看到它:angular.io/docs/ts/latest/api/common/index/…
科隆(Koslun)


1
谢谢,在docs网站上创建了一个关于缺少文档的问题,并引用了以下答案:github.com/angular/angular.io/issues/2553
Koslun,2016年

1
下调-1。ng-container并不是要避免自定义模板,而是要具有不包装在容器中的条件内容。实际上,自定义模板还将引入包装容器,即指令标记本身。
卡洛·鲁森

1
你是绝对正确的。这肯定是需要提及的区别。我已将提示添加到我的帖子中。
马特

-1

当您想将表与* ngIf和* ngFor一起使用时的用例-将div放入td / th 会使表元素不当 --。我遇到了这个问题,就是答案。


1
但是使用可以实现相同的目的<template [ngIf]...>。问题是这两种方法之间的区别。
Estus Flask

哦,我不好,它似乎在这里得到了答案stackoverflow.com/questions/40529537/…他们只是说这只是语法上的差异
shakram02
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.