* ngIf w innym przypadku, jeśli w szablonie

105

Jak miałbym mieć wiele przypadków w *ngIfwyciągu? Przywykłem do Vue lub kątowej 1 z mającą if, else ifi else, ale wydaje się, kanciasty 4 ma tylko true( if) i false( else) warunek.

Zgodnie z dokumentacją mogę tylko:

  <ng-container *ngIf="foo === 1; then first else second"></ng-container>
  <ng-template #first>First</ng-template>
  <ng-template #second>Second</ng-template>
  <ng-template #third>Third</ng-template>

Ale chcę mieć wiele warunków (coś w stylu):

  <ng-container *ngIf="foo === 1; then first; foo === 2; then second else third"></ng-container>
  <ng-template #first>First</ng-template>
  <ng-template #second>Second</ng-template>
  <ng-template #third>Third</ng-template>

Ale ostatecznie muszę użyć ngSwitch, co wydaje się hack:

  <ng-container [ngSwitch]="true">
    <div *ngSwitchCase="foo === 1">First</div>
    <div *ngSwitchCase="bar === 2">Second</div>
    <div *ngSwitchDefault>Third</div>
  </ng-container>

Alternatywnie, wygląda na to, że wiele składni, do których przyzwyczaiłem się z Angular 1 i Vue, nie jest obsługiwanych w Angular 4, więc jaki byłby zalecany sposób nadania struktury mojego kodu w takich warunkach?

Alexander Abakumov
źródło
Myślałem, że hack jest najlepszym rozwiązaniem, ponieważ jest najbardziej czytelny. Jednak zdałem sobie sprawę, że instrukcje przełącznika kątowego pozwalają na dopasowanie wielu kryteriów, więc nie otrzymujesz prawdziwej logiki elseif.
Tom Benyon

Odpowiedzi:

149

Inną alternatywą są warunki gniazdowe

<ng-container *ngIf="foo === 1;else second"></ng-container>
<ng-template #second>
    <ng-container *ngIf="foo === 2;else third"></ng-container>
</ng-template>
<ng-template #third></ng-template>
CornelC
źródło
4
To było dla mnie lepsze rozwiązanie. Moje warunki były oparte na wielu zmiennych i więcej niż jedna mogła być spełniona w tym samym czasie.
Matt DeKok
1
Nie możemy użyć <ng-template #second *ngIf="foo === 2;else third">
czegoś
sprytny. należy wprowadzić do ramy tbh
Pogrindis
36

Możesz po prostu użyć:

<ng-template [ngIf]="index == 1">First</ng-template>
<ng-template [ngIf]="index == 2">Second</ng-template>
<ng-template [ngIf]="index == 3">Third</ng-template>

chyba że część pojemnika ngowego jest ważna dla twojego projektu.

Oto Plunker

Dylan
źródło
1
Mój przykład jest trochę uproszczony, ale spodziewając się zachowania „else if” takiego, if (index === 1) else if (foo === 2)które musiałoby być napisane, if (index === 1) if (index !== 1 && foo === 2)które jest nieco niechlujne i bardziej podatne na błędy, im więcej razy będziemy musieli pisać logikę odwrotną.
Czy spojrzałeś na plunkra? Myślę, że nie widzę problemu, indeks będzie tylko jedną rzeczą naraz.
Dylan
Myślę, że to mój przykład nie ma wyjaśnienia, oto przykład w JS: if (item === 'food' && kind === 'hamburger') {} else if (item === 'food' && kind === 'hotdog') {} else if (item === 'drink' && kind === 'beer') {} else if (item === 'drink' && kind === 'wine') {} else { /* could be poisonous */ }
1
Wciąż zbyt wiele wzajemnych wykluczeń w tym przykładzie, ale nadal chodzi o to, że muszę zrobić, jeśli, inaczej, jeśli, a nie tylko wtedy, i jeszcze nie, bez pisania mnóstwa zbędnej logiki. Wygląda na to, że szablony Angular 4 nie mają takiej logiki.
1
jest kilka innych opcji, wygląda na to, że możesz skorzystać NgTemplateOutletz kontekstu takiego jak * ngTemplateOutlet = "drink; context: beer" lub może innego składnika do kategoryzacji.
Dylan
26

Wydaje się, że jest to najczystszy sposób

if (foo === 1) {

} else if (bar === 99) {

} else if (foo === 2) {

} else {

}

w szablonie:

<ng-container *ngIf="foo === 1; else elseif1">foo === 1</ng-container>
<ng-template #elseif1>
    <ng-container *ngIf="bar === 99; else elseif2">bar === 99</ng-container>
</ng-template>
<ng-template #elseif2>
    <ng-container *ngIf="foo === 2; else else1">foo === 2</ng-container>
</ng-template>
<ng-template #else1>else</ng-template>

Zauważ, że działaelse if to tak, jak powinna być właściwa instrukcja, gdy warunki dotyczą różnych zmiennych (tylko 1 przypadek jest prawdziwy na raz). Niektóre inne odpowiedzi nie działają w takim przypadku.

na bok: rany, kanciasty, to naprawdę brzydki else ifkod szablonu ...

Koza
źródło
18

Możesz użyć wielu sposobów na podstawie ostrożności:

  1. Jeśli zmienna jest ograniczony do konkretnego numeru lub String , najlepszym sposobem jest użycie ngSwitch lub ngIf:

    <!-- foo = 3 -->
    <div [ngSwitch]="foo">
        <div *ngSwitchCase="1">First Number</div>
        <div *ngSwitchCase="2">Second Number</div>
        <div *ngSwitchCase="3">Third Number</div>
        <div *ngSwitchDefault>Other Number</div>
    </div>
    
    <!-- foo = 3 -->
    <ng-template [ngIf]="foo === 1">First Number</ng-template>
    <ng-template [ngIf]="foo === 2">Second Number</ng-template>
    <ng-template [ngIf]="foo === 3">Third Number</ng-template>
    
    
    <!-- foo = 'David' -->
    <div [ngSwitch]="foo">
        <div *ngSwitchCase="'Daniel'">Daniel String</div>
        <div *ngSwitchCase="'David'">David String</div>
        <div *ngSwitchCase="'Alex'">Alex String</div>
        <div *ngSwitchDefault>Other String</div>
    </div>
    
    <!-- foo = 'David' -->
    <ng-template [ngIf]="foo === 'Alex'">Alex String</ng-template>
    <ng-template [ngIf]="foo === 'David'">David String</ng-template>
    <ng-template [ngIf]="foo === 'Daniel'">Daniel String</ng-template>
    
  2. Powyższe nie nadaje się do kodów if elseif else i kodów dynamicznych, możesz użyć poniższego kodu:

    <!-- foo = 5 -->
    <ng-container *ngIf="foo >= 1 && foo <= 3; then t13"></ng-container>
    <ng-container *ngIf="foo >= 4 && foo <= 6; then t46"></ng-container>
    <ng-container *ngIf="foo >= 7; then t7"></ng-container>
    
    <!-- If Statement -->
    <ng-template #t13>
        Template for foo between 1 and 3
    </ng-template>
    <!-- If Else Statement -->
    <ng-template #t46>
        Template for foo between 4 and 6
    </ng-template>
    <!-- Else Statement -->
    <ng-template #t7>
        Template for foo greater than 7
    </ng-template>
    

Uwaga: możesz wybrać dowolny format, ale zauważ, że każdy kod ma własne problemy

Sina Lotfi
źródło
1
IMO 2. powinno czytać *ngIf="foo >= 7; then t7"zamiast ... else t7.
hgoebl
Myślę, że tylko dwie linijki z drugą foo >= 4 && foo <= 6; then t46; else t7powinny działać.
Chmura
5

Aby uniknąć zagnieżdżania i ngSwitch, istnieje również taka możliwość, która wykorzystuje sposób działania operatorów logicznych w JavaScript:

<ng-container *ngIf="foo === 1; then first; else (foo === 2 && second) || (foo === 3 && third)"></ng-container>
  <ng-template #first>First</ng-template>
  <ng-template #second>Second</ng-template>
  <ng-template #third>Third</ng-template>
Max21
źródło
4

A może po prostu użyj łańcuchów warunkowych z operatorem trójargumentowym. if … else if … else if … elsełańcuch.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator#Conditional_chains

<ng-container *ngIf="isFirst ? first: isSecond ? second : third"></ng-container>

<ng-template #first></ng-template>
<ng-template #second></ng-template>
<ng-template #third></ng-template>

Bardziej podoba mi się to podejście.

Gerald Hughes
źródło
0

<ion-row *ngIf="cat === 1;else second"></ion-row>
<ng-template #second>
    <ion-row *ngIf="cat === 2;else third"></ion-row>
</ng-template>
<ng-template #third>

</ng-template>

Angular już używa ng-template pod maską w wielu dyrektywach strukturalnych, których używamy cały czas: ngIf, ngFor i ngSwitch.

> Co to jest szablon ng w Angular

https://www.angularjswiki.com/angular/what-is-ng-template-in-angular/

Supriya
źródło
0

Możesz także użyć tej starej sztuczki do konwersji złożonych bloków if / then / else w nieco czystszą instrukcję switch:

<div [ngSwitch]="true">
    <button (click)="foo=(++foo%3)+1">Switch!</button>

    <div *ngSwitchCase="foo === 1">one</div>
    <div *ngSwitchCase="foo === 2">two</div>
    <div *ngSwitchCase="foo === 3">three</div>
</div>
Michael Payne
źródło