* ngIf else se nel modello


101

Come avrei più casi in una *ngIfdichiarazione? Sono abituato a Vue o Angular 1 con un if, else ife else, ma sembra che Angular 4 abbia solo una condizione true( if) e false( else).

Secondo la documentazione, posso solo fare:

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

Ma voglio avere più condizioni (qualcosa di simile):

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

Ma finisco per dover usare ngSwitch, che sembra un hack:

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

In alternativa, sembra che molte delle sintassi a cui mi sono abituato da Angular 1 e Vue non siano supportate in Angular 4, quindi quale sarebbe il modo consigliato per strutturare il mio codice con condizioni come questa?


Pensavo che il tuo hack fosse la soluzione migliore perché era più leggibile. Tuttavia, mi sono reso conto che le dichiarazioni di commutazione angolare consentono la corrispondenza di più criteri in modo da non ottenere quella vera logica elseif.
Tom Benyon

Risposte:


144

Un'altra alternativa è alle condizioni di nidificazione

<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
Questa è stata la soluzione migliore per me. Le mie condizioni erano basate su più variabili e più di una poteva essere vera contemporaneamente.
Matt DeKok

1
Non possiamo usare come<ng-template #second *ngIf="foo === 2;else third">
Loki

intelligente. dovrebbe essere introdotto al quadro tbh
Pogrindis

36

Puoi semplicemente usare:

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

a meno che la parte ng-container non sia importante per il tuo design, suppongo.

Ecco un Plunker


1
Il mio esempio è un po 'semplicistico, ma aspettandoci il comportamento "else if" tale che if (index === 1) else if (foo === 2)dovrebbe essere scritto if (index === 1) if (index !== 1 && foo === 2)che è un po' disordinato e più incline agli errori, più volte dobbiamo scrivere la logica inversa.

Hai guardato il plunker? Non credo di vedere il problema, l'indice sarà solo 1 cosa alla volta.
Dylan

Penso che sia il mio esempio a mancare di spiegazioni, ecco un esempio in 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
Ancora troppa esclusione reciproca in quell'esempio, ma comunque, il punto è, devo fare se, altrimenti se, e altrimenti, non solo se e altro senza scrivere tonnellate di logica ridondante. Sembra che i modelli di Angular 4 manchino di questo tipo di logica.

1
ci sono poche altre opzioni, questo suona come potresti trarre vantaggio da un NgTemplateOutletcontesto come * ngTemplateOutlet = "drink; context: beer", o forse un altro componente per la categorizzazione.
Dylan

26

Questo sembra essere il modo più pulito per farlo

if (foo === 1) {

} else if (bar === 99) {

} else if (foo === 2) {

} else {

}

nel modello:

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

Si noti che funziona come else ifdovrebbe fare un'istruzione corretta quando le condizioni coinvolgono variabili diverse (è vero solo 1 caso alla volta). Alcune delle altre risposte non funzionano correttamente in questo caso.

a parte: accidenti angolare, è un else ifcodice modello davvero brutto ...


17

Puoi utilizzare più modi in base alla situazione:

  1. Se la variabile è limitata a un numero o una stringa specifici , il modo migliore è utilizzare ngSwitch o 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. Sopra non adatto per se altro se codici e codici dinamici, puoi usare il codice seguente:

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

Nota: puoi scegliere qualsiasi formato, ma nota che ogni codice ha i suoi problemi


1
IMO 2. dovrebbe leggere *ngIf="foo >= 7; then t7"invece di ... else t7.
hgoebl

Penso che foo >= 4 && foo <= 6; then t46; else t7dovrebbero funzionare solo due righe con la seconda .
Cloud

4

Per evitare annidamenti e ngSwitch, esiste anche questa possibilità, che sfrutta il modo in cui gli operatori logici funzionano in 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>



0

Puoi anche usare questo vecchio trucco per convertire complessi blocchi if / then / else in un'istruzione switch leggermente più pulita:

<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>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.