* ngIf else if in template


101

Як я маю кілька випадків у *ngIfзаяві? Я звик до Vue або кутовим 1 з наявністю if, else ifі else, але, схоже кутовим 4 має тільки true( if) і false( else) стан.

Згідно з документацією, я можу робити лише:

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

Але я хочу мати кілька умов (щось на зразок):

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

Але мені в кінцевому підсумку доводиться використовувати ngSwitch, що відчуває себе як хак:

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

З іншого боку, здається, що багато синтаксисів, до яких я звик з Angular 1 та Vue, не підтримуються в Angular 4, тож яким буде рекомендований спосіб структурувати мій код за таких умов?


Я думав, що ви зламали найкраще рішення, оскільки воно було найбільш читабельним. Однак я зрозумів, що оператори перемикання кутів дозволяють збігатися кільком критеріям, тому ви не отримуєте цієї справжньої логіки elseif.
Том

Відповіді:


145

Інша альтернатива - умови гніздування

<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
Це було найкраще рішення для мене. Мої умови базувались на декількох змінних, і більше, ніж одна, могла бути істинною одночасно.
Метт ДеКок,

1
Чи не можемо ми використати як<ng-template #second *ngIf="foo === 2;else third">
Локі

кмітливий. слід ввести в основи
tbh

36

Ви можете просто використовувати:

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

окрім випадків, коли частина ng-контейнера важлива для вашого дизайну.

Ось Планкер


1
Мій приклад трохи спрощений, але очікуючи поведінки "else if", такої, if (index === 1) else if (foo === 2)яку потрібно було б написати, if (index === 1) if (index !== 1 && foo === 2)яка є дещо безладною і більш схильною до помилок, тим більше разів нам доводиться писати зворотну логіку.

Ти дивився на плункера? Я не думаю, що бачу проблему, індекс одночасно складатиме лише 1 річ.
Ділан,

Я думаю, що моєму прикладу не вистачає пояснень, ось приклад у 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
У цьому прикладі все ще занадто багато взаємного виключення, але все-таки справа в тому, що мені потрібно робити if, else if, і ще, а не просто if і else без написання тонн зайвої логіки. Здається, у шаблонах Angular 4 відсутня така логіка.

1
є кілька інших варіантів, це схоже на те, що вам може скористатись такий NgTemplateOutletконтекст, як * ngTemplateOutlet = "drink; context: beer", або, можливо, інший компонент для категоризації.
Ділан,

26

Здається, це найчистіший спосіб зробити

if (foo === 1) {

} else if (bar === 99) {

} else if (foo === 2) {

} else {

}

у шаблоні:

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

Зверніть увагу, що це працює як належне else ifтвердження, коли умови включають різні змінні (лише 1 випадок істинний за раз). Деякі інші відповіді не працюють правильно в такому випадку.

вбік: боже кутовий, це якийсь справді потворний else ifкод шаблону ...


17

Ви можете використовувати кілька способів на основі ситуації:

  1. Якщо ви Мінлива обмежена конкретним Кількість або рядки , кращий спосіб використовує ngSwitch або 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. Вище не підходить для інших кодів та динамічних кодів, ви можете використовувати нижче код:

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

Примітка. Ви можете вибрати будь-який формат, але зверніть увагу, що кожен код має свої проблеми


1
IMO 2. слід читати *ngIf="foo >= 7; then t7"замість ... else t7.
hgoebl

Я думаю, що foo >= 4 && foo <= 6; then t46; else t7повинні працювати лише два рядки з другим .
Хмара

4

Щоб уникнути вкладеності та ngSwitch, існує також така можливість, яка використовує спосіб роботи логічних операторів у 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>

2

А може просто використовувати умовні ланцюжки з потрійним оператором. if … else if … else if … elseланцюжок.

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>

Мені подобається цей підхід більше.


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 вже використовує ng-шаблон під капотом у багатьох структурних директивах, які ми постійно використовуємо: ngIf, ngFor та ngSwitch.

> Що таке ng-шаблон в Angular

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


0

Ви також можете використовувати цей старий трюк для перетворення складних блоків if / then / else у дещо чистіший оператор перемикання:

<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>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.