* ngIf else if in template

101

Comment pourrais-je avoir plusieurs cas dans une *ngIfdéclaration? Je suis habitué à Vue ou angulaire 1 d'avoir un if, else ifet else, mais il semble que angulaire 4 a seulement true( if) et false( else) condition.

D'après la documentation, je ne peux que faire:

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

Mais je veux avoir plusieurs conditions (quelque chose comme):

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

Mais je finis par devoir utiliser ngSwitch, ce qui ressemble à un hack:

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

Alternativement, il semble que beaucoup de syntaxes auxquelles je suis habitué à partir d'Angular 1 et Vue ne sont pas prises en charge dans Angular 4, alors quelle serait la manière recommandée de structurer mon code avec des conditions comme celle-ci?

Alexandre Abakumov
la source
Je pensais que vous pirater était la meilleure solution car elle était la plus lisible. Cependant, j'ai réalisé que les instructions de commutation angulaire permettent à plusieurs critères de correspondre afin que vous n'obteniez pas cette vraie logique elseif.
Tom Benyon

Réponses:

145

Une autre alternative consiste à imbriquer les conditions

<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
la source
4
C'était la meilleure solution pour moi. Mes conditions étaient basées sur plusieurs variables et plus d'une étaient capables d'être vraies en même temps.
Matt DeKok
1
Ne pouvons-nous pas utiliser comme<ng-template #second *ngIf="foo === 2;else third">
Loki
intelligent. devrait être présenté au framework tbh
Pogrindis le
36

Vous pouvez simplement utiliser:

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

sauf si la partie ng-container est importante pour votre conception, je suppose.

Voici un Plunker

Dylan
la source
1
Mon exemple est un peu simpliste, mais en attendant le comportement «sinon si» tel que celui if (index === 1) else if (foo === 2)qui devrait être écrit if (index === 1) if (index !== 1 && foo === 2)qui est un peu brouillon et plus sujet aux erreurs, plus nous devons écrire de la logique inverse.
Avez-vous regardé le plunker? Je ne pense pas voir le problème, l'index ne sera qu'une chose à la fois.
Dylan
Je pense que c'est mon exemple qui manque d'explication, voici un exemple dans 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
Encore trop d'exclusion mutuelle dans cet exemple, mais le fait est que je dois faire si, sinon si et sinon, pas seulement si et sinon sans écrire des tonnes de logique redondante. Il semble que les modèles d'Angular 4 manquent de ce type de logique.
1
il y a quelques autres options, cela semble que vous pourriez bénéficier d'un NgTemplateOutletcontexte comme * ngTemplateOutlet = "drink; context: beer", ou peut-être un autre composant pour la catégorisation.
Dylan
26

Cela semble être la manière la plus propre de faire

if (foo === 1) {

} else if (bar === 99) {

} else if (foo === 2) {

} else {

}

dans le modèle:

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

Notez que cela fonctionne comme une else ifinstruction appropriée devrait lorsque les conditions impliquent différentes variables (un seul cas est vrai à la fois). Certaines des autres réponses ne fonctionnent pas correctement dans un tel cas.

à part: gosh angular, c'est un else ifcode de modèle vraiment moche ...

chèvre
la source
17

Vous pouvez utiliser plusieurs méthodes basées sur la prudence:

  1. Si votre variable est limitée à un nombre ou une chaîne spécifique , le meilleur moyen est d'utiliser ngSwitch ou 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. Ci-dessus ne convient pas pour if elseif sinon codes et codes dynamiques, vous pouvez utiliser le code ci-dessous:

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

Remarque: vous pouvez choisir n'importe quel format, mais notez que chaque code a ses propres problèmes

Sina Lotfi
la source
1
IMO 2. devrait lire *ngIf="foo >= 7; then t7"au lieu de ... else t7.
hgoebl
Je pense que juste deux lignes avec la seconde foo >= 4 && foo <= 6; then t46; else t7devraient fonctionner.
Nuage
4

Pour éviter l'imbrication et ngSwitch, il existe également cette possibilité, qui exploite le fonctionnement des opérateurs logiques en 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
la source
2

Ou peut-être simplement utiliser des chaînes conditionnelles avec un opérateur ternaire. if … else if … else if … elsechaîne.

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>

J'aime mieux cette approche.

Gerald Hughes
la source
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 utilise déjà ng-template sous le capot dans de nombreuses directives structurelles que nous utilisons tout le temps: ngIf, ngFor et ngSwitch.

> Qu'est-ce que ng-template dans Angular

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

Supriya
la source
0

Vous pouvez également utiliser cette vieille astuce pour convertir des blocs if / then / else complexes en une instruction switch légèrement plus propre:

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