Czy ktoś może zilustrować różnicę między użyciem <ng-container>
a <ng-template>
elementami?
Nie mogłem znaleźć dokumentacji dla NgContainer
i nie do końca rozumiem różnicę między tagiem szablonu.
Przykład kodu każdego z nich byłby bardzo pomocny.
Odpowiedzi:
Oba są w tej chwili (2.x, 4.x) używane do grupowania elementów bez konieczności wprowadzania kolejnego elementu, który zostanie wyrenderowany na stronie (np. div
Lub span
).
template
jednak wymaga okropnej składni. Na przykład,
<li *ngFor="let item of items; let i = index; trackBy: trackByFn">...</li>
stanie się
<template ngFor let-item [ngForOf]="items" let-i="index" [ngForTrackBy]="trackByFn">
<li>...</li>
</template>
Możesz użyć ng-container
zamiast tego, ponieważ jest on zgodny z ładną *
składnią, której oczekujesz i prawdopodobnie już znasz.
<ng-container *ngFor="let item of items; let i = index; trackBy: trackByFn">
<li>...</li>
</ng-container>
Więcej szczegółów można znaleźć, czytając tę dyskusję w serwisie GitHub .
Zauważ, że w 4.x <template>
jest przestarzałe i zmienione na <ng-template>
.
Posługiwać się
<ng-container>
jeśli potrzebujesz elementu pomocniczego dla zagnieżdżonych dyrektyw strukturalnych, takich jak *ngIf
lub, *ngFor
lub jeśli chcesz zawinąć więcej niż jeden element wewnątrz takiej dyrektywy strukturalnej;<ng-template>
jeśli potrzebujesz widok „snippet”, który ma na znaczek w różnych miejscach za pomocą ngForTemplate
, ngTemplateOutlet
, lub createEmbeddedView()
.ng-template
jest używany w przypadku dyrektywy strukturalnej, takiej jak ng-if
, ng-for
i ng-switch
. Jeśli użyjesz go bez dyrektywy strukturalnej, nic się nie dzieje i zostanie wyrenderowany.
ng-container
jest używany, gdy nie masz odpowiedniego opakowania lub pojemnika nadrzędnego. W większości przypadków używamy div
lub span
jako kontenera, ale w takich przypadkach, gdy chcemy użyć wielu dyrektyw strukturalnych. Ale nie możemy użyć więcej niż jednej dyrektywy strukturalnej na elemencie, w takim przypadku ng-container
można go użyć jako kontenera
ng-template jest kątowym elementem renderowania HTML. Nigdy nie jest wyświetlana bezpośrednio. Używaj w przypadku dyrektyw strukturalnych, takich jak: ngIf, ngFor, ngSwitch, .. Przykład :<ng-template>
<div *ngIf="hero" class="name">{{hero.name}}</div>
Angular tłumaczy atrybut * ngIf na <ng-template>
element owinięty wokół elementu hosta, w ten sposób.
<ng-template [ngIf]="hero">
<div class="name">{{hero.name}}</div>
</ng-template>
ng-container
Użyj jako elementu grupującego, gdy nie ma odpowiedniego elementu hosta.
Przykład:
<div>
Pick your favorite hero
(<label><input type="checkbox" checked (change)="showSad = !showSad">show sad</label>)
</div>
<select [(ngModel)]="hero">
<span *ngFor="let h of heroes">
<span *ngIf="showSad || h.emotion !== 'sad'">
<option [ngValue]="h">{{h.name}} ({{h.emotion}})</option>
</span>
</span>
</select>
To nie zadziała. Ponieważ niektóre elementy HTML wymagają, aby wszystkie bezpośrednie elementy potomne były określonego typu. Na przykład <select>
element wymaga dzieci. Nie możesz zawijać opcji w warunek lub <span>
.
Spróbuj tego :
<div>
Pick your favorite hero
(<label><input type="checkbox" checked (change)="showSad = !showSad">show sad</label>)
</div>
<select [(ngModel)]="hero">
<ng-container *ngFor="let h of heroes">
<ng-container *ngIf="showSad || h.emotion !== 'sad'">
<option [ngValue]="h">{{h.name}} ({{h.emotion}})</option>
</ng-container>
</ng-container>
</select>
To zadziała.
Więcej informacji: Dyrektywa strukturalna kątowa
ng-template
jak sama nazwa wskazuje, oznacza szablon . Sam w sobie niczego nie renderuje. Możemy użyć ng-container
znaku zastępczego do dynamicznego renderowania szablonu .
Innym przykładem użycia ng-template
jest to, że możemy go użyć do zagnieżdżenia wielu dyrektyw strukturalnych razem. Możesz znaleźć świetne przykłady tutaj w tym poście na blogu: angular ng-template / ng-container
Mówiąc prościej, ng-container
jest jak wyższy komponent Reacta , który tylko pomaga w renderowaniu jego elementów potomnych.
ng-template
jest w zasadzie do wewnętrznej implementacji Angulara , gdzie wszystko wewnątrz ng-template
jest całkowicie ignorowane podczas renderowania i zasadniczo staje się komentarzem do źródła widoku. Ma to być używane z wewnętrznymi dyrektywami Angulara ngIf
, takimi jak ngSwitch
itp.
Podoba mi <ng-container>
się sposób na jak największe oddzielenie „logiki” od „znaczników” w plikach Angular .component.html.
(częściowy) przykład renderowania wierszy tabeli html:
<ng-container *ngFor="let product of products">
<tr>
<td></td>
<td>{{ product.productName }}</td>
<td>{{ product.productCode }}</td>
<td>{{ product.releaseDate }}</td>
<td>{{ product.price }}</td>
<td>{{ product.starRating }}</td>
</tr>
</ng-container>
W ten sposób, jeśli chcę zmienić HTML <table>
na coś innego, na przykład kilka <div>
stylów ze stylem flexbox, nie muszę „wyrzeźbić” logiki zapętlenia (lub ryzykować całkowitą utratę) od wewnątrz <tr>
. Chroni również logikę zapętlania (ngFor) przed częściowym zasłonięciem przez normalny kod HTML.
@Input()
s.*
jest oczywiście wygodniejszy. Ale masz rację,<ng-container>
został wprowadzony, ponieważ różnice w składni spowodowały spore zamieszanie.