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

ng-containerofficial 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; 如何在自定义指令中使用?

【问题讨论】:

    标签: angular typescript angular2-template


    【解决方案1】:

    ng-container 的 Imo 用例是简单的替换,自定义模板/组件可能会过度使用。在 API 文档中,他们提到了以下内容

    使用 ng-container 对多个根节点进行分组

    我猜这就是它的全部意义:分组。

    请注意,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;来实现。问题是这两种方法之间的区别。
    • 哦,我的错,似乎在这里回答stackoverflow.com/questions/40529537/…他们只是说这只是语法差异
    【解决方案5】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-09
      • 2017-03-24
      • 2019-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-25
      相关资源
      最近更新 更多