Анатомия проекта и первый компонент

Компонент — это атом интерфейса Angular: класс с данными и поведением, склеенный с куском HTML и CSS через декоратор.

«Если вы понимаете один компонент, вы понимаете всё приложение — оно просто состоит из тысячи таких же».

После ng new вас встречает папка с десятком файлов. Не пугайтесь — большинство трогать не придётся. Ключевые места: src/main.ts — точка входа, которая запускает приложение; src/app/ — ваш код; angular.json — конфигурация сборки. Сердце всего — компоненты, и сейчас мы напишем свой.

Современный Angular-компонент standalone: он сам объявляет, что ему нужно, без посредников вроде NgModule. Создадим его через CLI:

ng generate component product-card

CLI создаст четыре файла: класс, шаблон, стили и тест. Вот сердцевина — класс с декоратором @Component:

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

@Component({
  selector: 'app-product-card',
  standalone: true,
  template: `
    <article class="card">
      <h2>{{ title }}</h2>
      <p>Цена: {{ price }} ₽</p>
    </article>
  `,
  styles: [`.card { border: 1px solid #ddd; padding: 16px; }`],
})
export class ProductCardComponent {
  title = 'Кофемолка';
  price = 2990;
}

Декоратор @Component — это метаданные: selector задаёт имя тега (<app-product-card>), template — разметку, styles — стили, изолированные от остального приложения. Внутри шаблона двойные фигурные скобки {{ }} — это интерполяция: Angular подставляет значение свойства класса прямо в текст.

Как работает под капотом

Декоратор @Component — это функция, которая «навешивает» на класс метаданные. При сборке Angular-компилятор читает их и генерирует код, который умеет создавать DOM-узлы и связывать их со свойствами класса. Когда title меняется, change detection обновляет текстовый узел.

  @Component({...})   <- метаданные (selector, template)
        |
        v
   class ProductCard  <- данные (title, price) + методы
        |
   [ Angular-компилятор ]
        |
        v
   фабрика, создающая <article>...</article> в DOM

Частые ошибки

  • Селектор без префикса. Используйте app- (или свой), чтобы не конфликтовать со стандартными HTML-тегами.
  • Забыть standalone: true в ручном коде — в старых проектах компонент мог требовать NgModule. В Angular 19 standalone — значение по умолчанию.
  • Логика в шаблоне. Интерполяция {{ }} для вычислений с побочными эффектами — антипаттерн; считайте значения в классе.

Best practices

  • Один компонент — одна папка с четырьмя файлами; не сваливайте всё в один.
  • Имена компонентов оканчивайте на Component, селекторы — в kebab-case.
  • Маленькие шаблоны держите inline, большие выносите в отдельный .html.

Итоги. Компонент = класс + декоратор @Component с шаблоном и стилями. Standalone-компоненты самодостаточны. Интерполяция {{ }} выводит данные класса в разметку. Дальше научим компоненты общаться.

Закрепляем

Компонент — это союз четырёх вещей: класса (данные и поведение), шаблона (что видит пользователь), стилей (как это выглядит) и метаданных в декораторе @Component (как всё связать). Когда вы научитесь читать эти четыре части как единое целое, любой чужой компонент станет для вас открытой книгой — ведь всё приложение собрано из таких же кубиков.

Отдельно стоит запомнить про изоляцию стилей. По умолчанию стили, объявленные в компоненте, не «протекают» наружу и не задевают другие компоненты — Angular добавляет к ним технические атрибуты, ограничивая область действия. Это огромное облегчение в больших проектах: вам не нужно бояться, что класс .card в одном месте сломает вёрстку в другом. Каждый компонент живёт в своём стилевом пузыре, и это снимает целый класс головной боли, знакомый по обычной разработке на чистом CSS.

Поле @ComponentНазначение
selectorИмя тега для вставки компонента
template / templateUrlРазметка компонента
styles / styleUrlsИзолированные стили
standaloneСамодостаточность (по умолчанию true в v19)
Проверьте себя
1. Что задаёт поле selector в декораторе @Component?
AЦвет компонента
BИмя HTML-тега, под которым компонент вставляется в шаблон
CИмя файла
DАдрес маршрута
2. Что делает синтаксис {{ title }} в шаблоне?
AСоздаёт цикл
BИнтерполяция: подставляет значение свойства класса в текст разметки
CОбъявляет переменную
DИмпортирует модуль