Что такое Angular: фреймворк, компоненты, шаблоны и директивы

Что такое Angular: фреймворк, компоненты, шаблоны и директивы Полезное

Angular — это фреймворк с открытым кодом от Google для создания веб-приложений, чаще всего одностраничных (SPA), на языке TypeScript. Приложение на Angular собирается из компонентов: каждый — это класс TypeScript, HTML-шаблон и стили. Поведение шаблона задают привязки, директивы (например, *ngIf) и встроенные блоки управления (@if, @for).

Angular не то же самое, что AngularJS: это старый фреймворк версий 1.x на JavaScript, его поддержка Google завершена 31 декабря 2021 года. Ниже — из чего состоит Angular-приложение, как работают шаблоны и директивы, чем *ngIf отличается от @if и атрибута hidden. Примеры проверены на Angular 22.2 (сентябрь 2026).

Мини-словарь

Термин Что это Пример
Angular Фреймворк версий 2+ на TypeScript @angular/core 22.x
AngularJS Фреймворк 1.x на JavaScript, поддержка завершена ng-app, $scope
Компонент Класс + шаблон + стили, свой тег <app-user-card>
Шаблон HTML с привязками Angular {{ user.name }}
Директива Класс, который меняет поведение или структуру элемента *ngIf, [ngClass]
Блок управления Встроенный синтаксис шаблона с Angular 17 @if, @for, @switch

Что входит в Angular

Angular называют фреймворком, а не библиотекой, потому что основные задачи веб-приложения в нем решены «из коробки» и одним способом:

  • компоненты и шаблоны с компиляцией шаблонов заранее (AOT);
  • внедрение зависимостей (DI) для сервисов;
  • маршрутизация (@angular/router), формы (@angular/forms), HTTP-клиент;
  • сигналы (signal, computed) для реактивного состояния;
  • Angular CLI — создание проекта, сборка, запуск тестов, генерация кода и миграции.

Для сравнения: React — библиотека для UI, а роутер, работу с формами и запросами команда выбирает сама. Это упрощенное сравнение: у обоих подходов есть экосистема, но в Angular набор частей и структура проекта заданы жестче. Поэтому его часто берут для крупных корпоративных приложений, где важны единые правила для большой команды.

Компонент: минимальный пример

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

// user-card.ts
import { Component, input } from '@angular/core';

export interface User {
  name: string;
  email: string;
}

@Component({
  selector: 'app-user-card',
  template: `
    @if (user(); as u) {
      <p class="name">{{ u.name }}</p>
      <p class="email">{{ u.email }}</p>
    } @else {
      <p class="empty">Пользователь не выбран</p>
    }
  `,
})
export class UserCard {
  user = input<User | null>(null);
}
// app.ts
import { Component, signal } from '@angular/core';
import { UserCard, User } from './user-card';

@Component({
  selector: 'app-root',
  imports: [UserCard],
  template: `
    <h1>{{ title }}</h1>
    <app-user-card [user]="current()" />
    <app-user-card [user]="null" />
  `,
})
export class App {
  title = 'Карточки пользователей';
  current = signal<User | null>({ name: 'Анна', email: 'anna@example.com' });
}

Angular отрисует такую разметку (служебные комментарии убраны):

<app-root ng-version="22.2.0"><h1>Карточки пользователей</h1><app-user-card><p class="name">Анна</p><p class="email">anna@example.com</p></app-user-card><app-user-card><p class="empty">Пользователь не выбран</p></app-user-card></app-root>

Разбор по частям:

  • @Component — декоратор, который превращает класс в компонент. selector — имя тега, под которым компонент вставляется в чужие шаблоны.
  • imports: [UserCard] — компонент явно подключает то, что использует в шаблоне. Это standalone-компоненты: с Angular 19 они по умолчанию, модули NgModule для нового кода не нужны.
  • input<User | null>(null) — входной параметр компонента, значение приходит от родителя через [user]="...".
  • signal(...) — реактивное значение. В шаблоне его читают вызовом: current().
  • Код пишется в .ts-файлах на TypeScript: типы (User | null) проверяются при сборке, в том числе внутри шаблона.

Шаблоны: четыре вида привязок

Шаблон Angular — обычный HTML плюс синтаксис, который связывает его с классом компонента.

Синтаксис Направление Пример Что делает
{{ выражение }} класс -> шаблон {{ u.name }} Выводит значение как текст
[свойство] класс -> шаблон [user]="current()" Передает значение в свойство элемента или input компонента
(событие) шаблон -> класс (click)="save()" Вызывает метод при событии
[(свойство)] в обе стороны [(ngModel)]="query" Двусторонняя привязка (для ngModel нужен FormsModule)

Интерполяция экранирует HTML: если в u.name окажется строка с тегом <script>, она выведется как текст, а не выполнится. Если HTML нужно именно отрисовать, используют привязку [innerHTML]: Angular сам санитизирует такое значение — теги оформления остаются, а <script> и атрибуты вроде onerror вырезаются (в консоли появится предупреждение sanitizing HTML stripped some content). Опасно обходить эту защиту через DomSanitizer.bypassSecurityTrustHtml для данных, пришедших от пользователя.

Директивы: три вида

Директива — класс, который Angular применяет к элементу шаблона. Виды:

  1. Компоненты — директивы со своим шаблоном (<app-user-card>).
  2. Атрибутные директивы меняют вид или поведение существующего элемента: [ngClass], [ngStyle], ngModel.
  3. Структурные директивы добавляют и удаляют элементы: *ngIf, *ngFor, *ngSwitchCase. Звездочка — синтаксический сахар: Angular оборачивает элемент в <ng-template> и сам решает, создавать ли его содержимое.

С Angular 17 для условий и циклов появились встроенные блоки @if, @for, @switch. В Angular 20 директивы NgIf, NgFor и NgSwitch помечены устаревшими (deprecated) в пользу блоков. В Angular 22.2 *ngIf еще работает, но для нового кода рекомендуется @if.

*ngIf, @if и hidden: в чем разница

Все три способа «прячут» элемент по условию, но делают это по-разному. Пример с условием isAdmin = false:

// app.ts
import { Component, signal } from '@angular/core';
import { NgIf } from '@angular/common';

@Component({
  selector: 'app-root',
  imports: [NgIf],
  template: `
    @if (isAdmin()) {
      <p class="a">Блок if: панель администратора</p>
    }
    <p class="b" *ngIf="isAdmin()">ngIf: панель администратора</p>
    <p class="c" [hidden]="!isAdmin()">hidden: панель администратора</p>
  `,
})
export class App {
  isAdmin = signal(false);
}

Результат отрисовки:

<app-root ng-version="22.2.0"><p class="c" hidden="">hidden: панель администратора</p></app-root>

Элементы a и b в DOM отсутствуют полностью, а элемент c остался — браузер лишь не показывает его из-за атрибута hidden.

Способ Элемент в DOM при false Состояние вложенных компонентов Нужен импорт
@if Удаляется Уничтожается, при true создается заново Нет
*ngIf Удаляется Уничтожается, при true создается заново NgIf или CommonModule
[hidden] Остается Сохраняется, компонент продолжает работать Нет

Как выбирать: @if — по умолчанию для условного вывода. [hidden] — когда элемент часто переключается и важно сохранить его состояние (например, заполненную форму во вкладке).

Граница у [hidden]: атрибут скрывает элемент стилем браузера display: none, и собственный CSS вроде .c { display: flex } его перебивает — элемент снова станет видимым. И главное: [hidden] не защищает данные. Разметка скрытой «панели администратора» все равно приходит в браузер, поэтому права доступа проверяются на сервере, а не в шаблоне.

Условие с else: старый и новый синтаксис

В коде, написанном до Angular 17, вы встретите *ngIf с веткой else через <ng-template>:

<p *ngIf="user() as u; else guest">Привет, {{ u.name }}</p>
<ng-template #guest>
  <p>Войдите, чтобы продолжить</p>
</ng-template>

То же самое на блоках — короче и без шаблонной переменной #guest:

@if (user(); as u) {
  <p>Привет, {{ u.name }}</p>
} @else {
  <p>Войдите, чтобы продолжить</p>
}

Оба варианта при user = null выводят <p>Войдите, чтобы продолжить</p>. Для перевода проекта со старого синтаксиса у Angular CLI есть миграция ng generate @angular/core:control-flow; после нее проект стоит собрать и прогнать тесты.

Мелкая ловушка нового синтаксиса: символ @ в тексте шаблона теперь начинает блок. Строка <p>@if: подсказка</p> не собирается с ошибкой NG5002: Incomplete block "if". If you meant to write the @ character, you should use the "&#64;" HTML entity instead. — как подсказывает сам текст, символ пишут сущностью &#64;.

Типичная ошибка: Cannot read properties of null

Данные пользователя часто приходят с сервера не сразу, и в первый момент значение равно null. Неверный шаблон:

<p>Привет, {{ user().name }}</p>

При строгой проверке шаблонов сборка остановится (в проекте, созданном Angular CLI 22, она действует по умолчанию; в старых проектах за нее отвечает флаг strictTemplates в tsconfig.json):

error TS2531: Object is possibly 'null'.

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

ERROR TypeError: Cannot read properties of null (reading 'name')

Исправление — явно обработать пустое значение через @if с @else, как в разделе выше. Если нужен только текст, подойдет оператор безопасной навигации {{ user()?.name }}: при null он выведет пустую строку без ошибки.

Angular и AngularJS: сравнение

Признак AngularJS (1.x) Angular (2+)
Годы 2010 — 2021 с 2016, актуальная ветка 22.x
Язык JavaScript TypeScript
Строительный блок Контроллер + $scope Компонент
Условие в шаблоне ng-if="..." @if (...) или *ngIf="..."
Поддержка Завершена 31.12.2021 Мажорный релиз примерно раз в полгода

Код между ними не переносится напрямую: это разные фреймворки с общим названием. Если в вакансии или учебнике встречаются $scope, ng-app и ng-controller — речь про AngularJS, и для нового проекта этот материал не подходит.

Выводы

  • Angular — фреймворк на TypeScript для веб-приложений, в котором роутинг, формы, HTTP, DI и CLI входят в стандартный набор.
  • Приложение строится из компонентов: класс, шаблон и стили; данные передаются через input-параметры и сигналы.
  • Шаблон связан с классом четырьмя видами привязок: {{ }}, [ ], ( ), [( )].
  • Для условий в новом коде используют блок @if; *ngIf устарел с Angular 20, но еще работает. Оба удаляют элемент из DOM, а [hidden] только скрывает его.
  • AngularJS — другой фреймворк версий 1.x, его поддержка завершена в 2021 году.

Где применяется / связь с практикой

Angular чаще всего встречается в корпоративных веб-приложениях: банковские и страховые кабинеты, внутренние системы, админ-панели с большим количеством форм и таблиц. Разработчику на Angular в работе нужны TypeScript, компоненты и сигналы, маршрутизация, реактивные формы, работа с HTTP и тестирование.

Освойте тему на практике

Системно эти темы — от первого компонента до архитектуры приложения — разбираются на курсе «Angular-разработчик». Чтобы познакомиться с форматом и преподавателями, можно начать с бесплатных открытых уроков.

FAQ

Как понять, на Angular или на AngularJS написан проект?
Посмотреть зависимости в package.json: пакеты @angular/core и @angular/common — это Angular, пакет angular версии 1.x — AngularJS.

Можно ли использовать *ngIf и @if в одном проекте?
Да, они работают вместе даже в одном шаблоне, поэтому старый код можно переводить на блоки постепенно.

Angular — это фронтенд или бэкенд?
Фронтенд: код выполняется в браузере. Angular умеет и серверную отрисовку (SSR), но это способ быстрее отдать страницу, а не замена серверной части с базой данных.

OTUS Журнал
Бесплатные открытые уроки (поп-ап)