<ng-container>と<template>


150

ng-container Angular 2のドキュメントで言及されていますが、それがどのように機能するか、そしてユースケースは何であるかについての説明はありません。

ngPluralngSwitchディレクティブで特に言及されています。

DOESは<ng-container>同じことを行う<template>、またはそれは、ディレクティブがそれらのいずれかを使用するために書かれたかどうかによって決まり?

ある

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

そして

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

同じはず?

それらの1つをどのように選択しますか?

<ng-container>カスタムディレクティブでどのように使用できますか?

回答:


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 2016

実際に<template></template>は、<script></script> これ
n00dl3

私の場合はそうではありませんでした。あっても<script>、コンパイル時に、DOMには、余分なタグが存在しない、その後削除されます。マニュアルには非推奨の情報が含まれているか、それが間違っていると思います。とにかく、<ng-container>と<template>の主な違いを指摘していただきありがとうございます。
Estus Flask 2016

リリース前は、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を使用できるため、2番目の方法が推奨されます。


素敵な説明、それはどのようにng-containerディレクティブのアイデアが生まれたのか、感謝の概要を提供します:)
Pankaj Parkar '

0

Imoのユースケースはng-container、カスタムテンプレート/コンポーネントではやりすぎになる単純な置換です。APIドキュメントでは、次のように述べています

ng-containerを使用して複数のルートノードをグループ化する

それがすべてのことだと思います。グループ化です。

ng-containerディレクティブが実際のコンテンツをラップするテンプレートではなく、ディレクティブが失われることに注意してください。


この言及へのリンクはありますか?現在、上記のリンクされたドキュメントと複数のケースのドキュメントで使用されているのは、angular.io / docs / ts / latest / api / common / index / …のみです。
Koslun、2016年


1
おかげで、ドキュメントの不足に関してドキュメントサイトで問題を作成し、この回答を参照しました:github.com/angular/angular.io/issues/2553
Koslun

1
-1に反対票を投じました。ng-containerは、カスタムテンプレートを回避することではなく、コンテナーにラップされない条件付きコンテンツを持つことができるようにすることです。実際、カスタムテンプレートは、ラッパーコンテナー、つまりディレクティブタグ自体も導入します。
Carlo Roosen

1
あなたは、絶対に正しい。それは確かに言及する必要がある違いです。ヒントを投稿に追加しました。
マット

-1

* ngIfおよび* ngForでテーブルを使用したい場合の使用例-divをtd / thに配置すると、テーブル要素が正しく動作しなくなります -。私はこの問題に直面し、それが答えでした。


1
しかし、同じことをで実現できます<template [ngIf]...>。問題は、これら2つのアプローチの違いでした。
Estus Flask 2017

ああ、私の悪いが、ここで答えているようだstackoverflow.com/questions/40529537/...彼らは単にそれだけの構文の違いだと言う
shakram02
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.