Czy ktoś może zilustrować różnicę między użyciem <ng-container>a <ng-template>elementami?
Nie mogłem znaleźć dokumentacji dla NgContaineri 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. divLub span).
templatejednak 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-containerzamiast 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 *ngIflub, *ngForlub 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-templatejest używany w przypadku dyrektywy strukturalnej, takiej jak ng-if, ng-fori ng-switch. Jeśli użyjesz go bez dyrektywy strukturalnej, nic się nie dzieje i zostanie wyrenderowany.
ng-containerjest używany, gdy nie masz odpowiedniego opakowania lub pojemnika nadrzędnego. W większości przypadków używamy divlub spanjako 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-containermoż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-templatejak sama nazwa wskazuje, oznacza szablon . Sam w sobie niczego nie renderuje. Możemy użyć ng-containerznaku zastępczego do dynamicznego renderowania szablonu .
Innym przykładem użycia ng-templatejest 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-containerjest jak wyższy komponent Reacta , który tylko pomaga w renderowaniu jego elementów potomnych.
ng-templatejest w zasadzie do wewnętrznej implementacji Angulara , gdzie wszystko wewnątrz ng-templatejest 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 ngSwitchitp.
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.