<ng-container> vs <template>

150

ng-container jest wspomniany w dokumentacji Angulara 2, ale nie ma wyjaśnienia, jak to działa i jakie są przypadki użycia.

Jest to szczególnie wspomniane w ngPluralingSwitch dyrektywach .

Robi <ng-container> robi to samo co <template>, czy też zależy to od tego, czy napisano dyrektywę, aby użyć jednego z nich?

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

i

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

powinien być taki sam?

Jak wybieramy jedną z nich?

Jak można <ng-container>używać w dyrektywie niestandardowej?

Estus Flask
źródło

Odpowiedzi:

244

Edycja: teraz jest to udokumentowane

<ng-container> na pomoc

Angular  <ng-container> to element grupujący, który nie koliduje ze stylami ani układem, ponieważ Angular nie umieszcza go w DOM.

(...)

Jest  <ng-container> to element składni rozpoznawany przez parser Angular. To nie jest dyrektywa, składnik, klasa ani interfejs. To bardziej przypomina nawiasy klamrowe w JavaScript if-block:

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

Bez tych nawiasów, JavaScript wykonałby pierwszą instrukcję tylko wtedy, gdy zamierzasz warunkowo wykonać je wszystkie jako pojedynczy blok. Na  <ng-container> spełnia podobna potrzeba w kątowe szablonów.

Oryginalna odpowiedź:

Zgodnie z tym żądaniem pull :

<ng-container> jest logicznym kontenerem, którego można używać do grupowania węzłów, ale nie jest renderowany w drzewie DOM jako węzeł.

<ng-container> jest renderowany jako komentarz HTML.

więc ten kątowy szablon:

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

wygeneruje taki wynik:

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

ng-containerJest więc przydatne, gdy chcesz warunkowo dołączyć grupę elementów (np. Używając *ngIf="foo") w swojej aplikacji, ale nie chcesz opakowywać ich innym elementem .

<div>
    <ng-container *ngIf="true">
        <h2>Title</h2>
        <div>Content</div>
    </ng-container>
</div>

wyprodukuje wtedy:

<div>
    <h2>Title</h2>
    <div>Content</div>
</div>
n00dl3
źródło
Trafne spostrzeżenie. Myślę, że różni się od tego, <template>gdy jest używany bez dyrektyw. w tym przypadku <template>będzie produkować <!--template bindings={}-->.
Estus Flask
faktycznie, <template></template>wyprodukuje <script></script> zobacz to
n00dl3
W moim przypadku tak nie było. Nawet jeśli jest <script>podczas kompilacji, jest później usuwany, w DOM nie ma żadnych dodatkowych tagów. Uważam, że podręcznik zawiera przestarzałe informacje lub po prostu zawiera błędy. W każdym razie dziękuję za wskazanie głównej różnicy między <ng-container> a <template>.
Estus Flask
Przed wydaniem Angular wyrenderował <script></script>. Renderował coś takiego <!--template bindings={}-->od dłuższego czasu. Dokumenty zostaną wkrótce naprawione.
Ward
40

Dokumentacja ( https://angular.io/guide/template-syntax#!#star-template ) podaje następujący przykład. Powiedzmy, że mamy taki kod szablonu:

<hero-detail *ngIf="currentHero" [hero]="currentHero"></hero-detail>

Zanim zostanie wyrenderowany, zostanie „pozbawiony cukru”. Oznacza to, że notacja asterix zostanie przepisana na notację:

<template [ngIf]="currentHero">
  <hero-detail [hero]="currentHero"></hero-detail>
</template>

Jeśli „currentHero” jest prawdziwe, zostanie to renderowane jako

<hero-detail> [...] </hero-detail>

Ale co, jeśli chcesz otrzymać warunkowe wyjście w ten sposób:

<h1>Title</h1><br>
<p>text</p>

.. i nie chcesz, aby wynik był opakowany w kontener.

Możesz napisać wersję pozbawioną cukru bezpośrednio w następujący sposób:

<template [ngIf]="showContent">
  <h1>Title</h1>
  <p>text</p><br>
</template>

I to będzie działać dobrze. Jednak teraz ngIf musi mieć nawiasy [] zamiast gwiazdki *, a to jest mylące ( https://github.com/angular/angular.io/issues/2303 )

Z tego powodu powstała inna notacja, jak na przykład:

<ng-container *ngIf="showContent"><br>
  <h1>Title</h1><br>
  <p>text</p><br>
</ng-container>

Obie wersje dadzą te same wyniki (renderowane będą tylko znaczniki h1 i p). Drugi jest preferowany, ponieważ możesz używać * ngIf jak zawsze.

Carlo Roosen
źródło
Ładne wyjaśnienie, zawiera przegląd tego, jak ng-containerpojawił się pomysł dyrektywy , dzięki :)
Pankaj Parkar
0

Przypadki użycia Imo ng-containerto proste zamienniki, dla których niestandardowy szablon / komponent byłby przesadą. W dokumencie API wspominają o następujących kwestiach

użyj kontenera ng, aby zgrupować wiele węzłów głównych

i myślę, że o to właśnie chodzi: grupowanie rzeczy.

Należy pamiętać, że ng-containerdyrektywa odpada zamiast szablonu, w którym jej dyrektywa otacza rzeczywistą zawartość.

Matt
źródło
Czy masz link do tej wzmianki? W tej chwili widzę go tylko w powyższej połączonej dokumentacji i dokumentacji przypadków w liczbie mnogiej: angular.io/docs/ts/latest/api/common/index/… .
Koslun
1
Dzięki, utworzyłem problem w witrynie dokumentacji dotyczący braku dokumentacji i odwołałem się do
Koslun
1
downvoted -1. ng-container nie polega na unikaniu niestandardowego szablonu, chodzi o możliwość posiadania warunkowej zawartości, która nie jest opakowana w kontener. W rzeczywistości niestandardowy szablon będzie również zawierał pojemnik opakowujący, a mianowicie sam znacznik dyrektywy.
Carlo Roosen
1
Masz absolutną rację. To z pewnością różnica, o której należy wspomnieć. Dodałem wskazówkę do mojego postu.
Matt,
-1

Przypadek użycia, gdy chcesz użyć tabeli z * ngIf i * ngFor - As wstawienie div w td / th spowoduje, że element tabeli będzie źle się zachowywał -. Zmierzyłem się z tym problemem i to była odpowiedź.

shakram02
źródło
1
Ale to samo można osiągnąć dzięki <template [ngIf]...>. Pytanie dotyczyło różnicy między tymi dwoma podejściami.
Estus Flask
och, moja wina, wydaje się, że odpowiedź tutaj stackoverflow.com/questions/40529537/ ... po prostu mówią, że to tylko różnica w składni
shakram02