Angular — это фреймворк с открытым кодом от Google для создания веб-приложений, чаще всего одностраничных (SPA), на языке TypeScript. Приложение на Angular собирается из компонентов: каждый — это класс TypeScript, HTML-шаблон и стили. Поведение шаблона задают привязки, директивы (например, *ngIf) и встроенные блоки управления (@if, @for).
Содержание
- Мини-словарь
- Что входит в Angular
- Компонент: минимальный пример
- Шаблоны: четыре вида привязок
- Директивы: три вида
- *ngIf, @if и hidden: в чем разница
- Условие с else: старый и новый синтаксис
- Типичная ошибка: Cannot read properties of null
- Angular и AngularJS: сравнение
- Выводы
- Где применяется / связь с практикой
- FAQ
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 применяет к элементу шаблона. Виды:
- Компоненты — директивы со своим шаблоном (
<app-user-card>). - Атрибутные директивы меняют вид или поведение существующего элемента:
[ngClass],[ngStyle],ngModel. - Структурные директивы добавляют и удаляют элементы:
*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 "@" HTML entity instead. — как подсказывает сам текст, символ пишут сущностью @.
Типичная ошибка: 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), но это способ быстрее отдать страницу, а не замена серверной части с базой данных.



