Условные конструкции и циклы

Последнее обновление: 14.11.2023

Одним из нововведений Angular 17 стало добавление во фреймворк новых синтаксических конструкций управления шаблоном компонента, которые позволяют легко определять условные и циклические конструкции. В предыдущих версиях Angular для этого применялись специальные директивы. Соответственно данная статья относится к версии Angular 17 и выше.

if

Конструкция if позволяет создавать условную конструкцию, как это делается в языке JavaScript. Например, определим следующий компонент:

import { Component} from "@angular/core";
import { FormsModule } from "@angular/forms";

@Component({
    selector: "my-app",
    standalone: true,
    imports: [FormsModule],
    template:`<div>
      <input [(ngModel)]="num" type="number" />
      @if(num==5){
        <p>Переменная num равна 5</p>
      }
    </div>`
})
export class AppComponent {
    num = 5;
}

Здесь в классе компонента определена переменная num. В шаблоне компонента с помощью конструкции

@if(num==5){
    <p>Переменная num равна 5</p>
}

проверяем, равна ли переменная num числу 5. Если равенство соблюдается, то выводится параграф с соответствующей информацией.

Для демонстрации я установил двустороннюю привязку переменной num к полю ввода, чтобы можно было динамически изменять ее значение:

Условные конструкции в Angular

С помощью выражений @else if() можно проверить дополнительные значения. А выражение @else позволяет установить код на случай, если предыдущие проверки в if/else if возвратили false:

import { Component} from "@angular/core";
import { FormsModule } from "@angular/forms";

@Component({
    selector: "my-app",
    standalone: true,
    imports: [FormsModule],
    template:`<div>
      <input [(ngModel)]="num" type="number" />
      @if(num==5){
        <p>Переменная num равна 5</p>
      } @else if(num==6){
        <p>Переменная num равна 6</p>
      } @else {
        <p>У переменной num неизвестное значение</p>
      }
    </div>`
})
export class AppComponent {
    num = 5;
}
Условные конструкции @if/@else if/@else в Angular

Если внутри конструкции надо вывести значение переменной, то оно, как и в общем случае, заключается в двойные фигурные скобки:

import { Component} from "@angular/core";
import { FormsModule } from "@angular/forms";

@Component({
    selector: "my-app",
    standalone: true,
    imports: [FormsModule],
    template:`<div>
      <input [(ngModel)]="age" min="1" type="number" />
      <h2>@if(age>0 && age < 110){
        Your age is {{age}}
      } @else {
        age is undefined
      }</h2>
    </div>`
})
export class AppComponent {
    age: number|undefined = undefined;
}

В данном случае если значение age представляет валидный возраст, то он выводится на страницу. Иначе выводится сообщение об ошибке.

switch

Конструкция switch, как и в javascript, позволяет сопоставить некоторое выражение с определенными значениями, которые указываются с помощью блоков @case. Например:

import { Component} from "@angular/core";
import { FormsModule } from "@angular/forms";

@Component({
    selector: "my-app",
    standalone: true,
    imports: [FormsModule],
    template:`<input [(ngModel)]="op" />
    <p>a = {{a}}  b = {{b}}</p>
  <p>Результат: 
      @switch (op) {
        @case ("+") {
          {{ a + b }}
        }
        @case ("-") {
          {{ a - b }}
        }
        @case ("*") {
          {{ a * b }}
        }
        @default {
          Неизвестная операция
        }
      }
    </p>`
})
export class AppComponent {
    op = "-"; // символ операции  
    a = 10;
    b = 5;
}

Здесь конструкция @switch проверяет значение переменной op, которая представляет собой символ операции, и зависимости ее значения выполняет определенную арифметическую операцию с числами a и b. Сравниваемые значение указываются после выражения @case. На тот случай, если ни одно из значений @case не соответствует проверяемому выражению, применяется выражение @default:

конструкция @switch..@case в Angular

Циклы и конструкция for

Конструкция @for позволяет создать цикл перебора коллекции. Например:

import { Component} from "@angular/core";

@Component({
    selector: "my-app",
    standalone: true,
    template:`<ul>
    @for (item of items; track item) {
          <li>{{ item }}</li>
    }
</ul>`
})
export class AppComponent {
    items = ["Tom", "Bob", "Sam"];
}

Здесь в конструкцию for передается массив items. При переборе каждый элемент этого массива помещается в переменную item, которую можно вывести на страницу в списке <ul>.

Кроме того, при переборе нам надо использовать выражение track/trackBy. Значение выражения track определяет ключ, используемый для связи элементов массива с представлениями в DOM. Подобное указание ключа элемента позволяет Angular выполнять минимальный набор операций DOM при добавлении, удалении или перемещении элементов в коллекции. В данном случае в качестве такого ключа применяется сам элемент (предположим, что в массиве имеются лишь уникальные имена) - track item

конструкция @for track в Angular

Однако в массиве могут быть и неуникальные значения. В этом случае команда Angular рекоммендует использовать специальное значение $index, которое внутри цикла указывает на индекс элемента в массиве.

@for (item of items; track $index) {
    <li>{{ item }}</li>
}

Кроме $index внутри цикла мы можем применять еще ряд специальных значений:

  • $count: количество элементов коллекции

  • $first: является ли текущий элемент первым в коллекции

  • $last: является ли текущий элемент последним в коллекции

  • $even: является ли индекс текущего элемента четным

  • $odd: является ли индекс текущего элемента нечетным

Применение некоторых значений:

@for (item of items; track $index) {
      <li>Item #{{ $index }}: {{ item }} {{$last?"(последний)":""}} {{$first?"(пeрвый)":""}}</li>
  }

Если применяются объекты, где уникальность определяется одним из свойств, например, идентификатором, то все несколько проще - можно использовать это свойство в качестве ключа:

import { Component} from "@angular/core";

class Item{
  constructor(public id: number, public name: string){}
}

@Component({
    selector: "my-app",
    standalone: true,
    template:`<ul>
   @for (item of items; track item.id) {
      <li>{{ item.name }}</li>
  }
</ul>`
})
export class AppComponent {
    items = [new Item(1, "Tom"), new Item(2, "Bob"), new Item(3,"Sam")];
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850