* ng, если иначе, если в шаблоне

105

Как мне включить в *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, так что каков был бы рекомендуемый способ структурировать мой код с такими условиями?

Александр Абакумов
источник
Я думал, что хакерство было лучшим решением, так как оно было наиболее читаемым. Однако я понял, что операторы angular switch допускают совпадение нескольких критериев, поэтому вы не получите эту истинную логику elseif.
Том

Ответы:

149

Другая альтернатива - условия гнездования.

<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
источник
4
Для меня это было лучшим решением. Мои условия основывались на нескольких переменных, и более чем одна могла быть верной одновременно.
Мэтт Декок 02
1
Разве мы не можем использовать подобное?<ng-template #second *ngIf="foo === 2;else third">
Локи
умная. должен быть введен в рамки tbh
Pogrindis
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-container не важна для вашего дизайна.

Вот плункер

Дилан
источник
1
Мой пример немного упрощен, но ожидая поведения «else if», такого, if (index === 1) else if (foo === 2)что нужно было бы написать, if (index === 1) if (index !== 1 && foo === 2)что немного беспорядочно и более подвержено ошибкам, тем больше раз нам придется писать обратную логику.
Вы смотрели на плункер? Я не думаю, что вижу проблему, index будет только по одной вещи за раз.
Дилан
Я думаю, что это мой пример без объяснения, вот пример на 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 и else, а не только 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должно когда в условиях используются разные переменные (за один раз истинен только один случай). Некоторые другие ответы не работают в таком случае.

в сторону: черт возьми, угловой, это действительно уродливый else ifкод шаблона ...

козел
источник
18

Вы можете использовать несколько способов в зависимости от ситуации:

  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. Выше не подходит для кодов if elseif else и динамических кодов, вы можете использовать следующий код:

    <!-- 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 02
Думаю, подойдут всего две строчки со второй foo >= 4 && foo <= 6; then t46; else t7.
Облако
6

Чтобы избежать вложенности и 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>
Макс21
источник
5

Или, может быть, просто используйте условные цепочки с тернарным оператором. 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-template под капотом во многих структурных директивах, которые мы используем все время: ngIf, ngFor и ngSwitch.

> Что такое ng-template в Angular

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

Суприя
источник
0

Вы также можете использовать этот старый трюк для преобразования сложных блоков if / then / else в более понятный оператор 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>
Майкл Пейн
источник