* 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?


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>

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


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 ...


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


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>

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.



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>
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.