Интерполяция и привязка свойств

Шаблон Angular — это HTML с суперспособностями: он умеет читать данные класса и менять разметку в реальном времени.

«Шаблон — это не статичная картинка, а живое окно в состояние компонента».

Связь между классом и разметкой называется привязкой данных (data binding). Мы уже видели интерполяцию {{ }}; теперь разложим все виды привязок по полочкам. Их три семейства: вывод значения в текст, привязка к свойству DOM-элемента и привязка к атрибуту/классу/стилю.

@Component({
  selector: 'app-profile',
  standalone: true,
  template: `
    <!-- 1. Интерполяция: значение в текст -->
    <h2>Привет, {{ name }}!</h2>

    <!-- 2. Property binding: свойство DOM -->
    <img [src]="avatarUrl" [alt]="name" />
    <button [disabled]="isLocked">Сохранить</button>

    <!-- 3. Class и style binding -->
    <span [class.active]="isOnline">статус</span>
    <div [style.width.px]="barWidth"></div>
  `,
})
export class ProfileComponent {
  name = 'Анна';
  avatarUrl = '/img/anna.png';
  isLocked = false;
  isOnline = true;
  barWidth = 240;
}

Ключевое различие: интерполяция {{ }} вставляет строку в текстовое содержимое, а property binding [ ] присваивает значение свойству объекта DOM напрямую. Поэтому [disabled]="isLocked" передаёт настоящий булев тип, а не строку «false», которая в HTML была бы истинной.

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

Каждая привязка превращается компилятором в инструкцию обновления. При обнаружении изменений Angular выполняет выражение справа от =, сравнивает результат с предыдущим и, если он изменился, обновляет конкретное свойство DOM. Никакого ручного document.querySelector — фреймворк держит карту «свойство класса → узел DOM».

   класс            привязка          DOM
   isLocked  --->  [disabled]  --->  button.disabled
   barWidth  --->  [style.width.px]  div.style.width

   change detection: значение изменилось? -> обновить узел

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

  • Кавычки в property binding. [title]="Привет" ищет свойство Привет; для строкового литерала нужно [title]="'Привет'" или просто title="Привет".
  • Путать attribute и property. [colspan] не сработает — у DOM-свойство называется иначе; для таких случаев есть [attr.colspan].
  • Сложные выражения в шаблоне. Привязка должна быть простой; вызов тяжёлых функций бьёт по производительности.

Best practices

  • Для условных классов предпочитайте [class.имя]="условие" — это читаемее, чем строковая склейка.
  • Не вызывайте методы в интерполяции в горячих местах — они выполняются на каждом цикле проверки.
  • Используйте [attr.*] только для настоящих HTML-атрибутов без DOM-свойства (ARIA, colspan).

Итоги. Интерполяция {{ }} выводит строки, [свойство] привязывается к свойствам DOM, [class.x] и [style.x] управляют видом. Дальше — события и двусторонняя привязка.

Закрепляем

Привязка данных — это клей между классом и разметкой, и важно держать в голове её направление. Интерполяция и property binding гонят данные из класса в DOM: вы меняете свойство — экран обновляется. Это односторонний поток сверху вниз. Запомните ключевую разницу: {{ }} кладёт строку в текст, а [ ] присваивает значение свойству DOM-объекта с сохранением типа, поэтому булевы и числовые привязки нужно делать именно через квадратные скобки.

Не путайте свойства DOM и HTML-атрибуты — это частый источник загадочных багов. Атрибут — это то, что написано в исходном HTML; свойство — это поле живого DOM-объекта, и они не всегда совпадают по имени. Большинство привязок работает со свойствами, и обычный [value] или [disabled] попадает в цель. Но для вещей вроде ARIA-атрибутов или colspan, у которых нет одноимённого DOM-свойства, существует особый синтаксис [attr.имя]. Знание этой развилки экономит часы отладки.

ПривязкаПример
Интерполяция{{ value }}
Property[disabled]="isLocked"
Class[class.active]="isOn"
Style[style.width.px]="w"
Проверьте себя
1. В чём разница между {{ value }} и [prop]="value"?
AНикакой разницы
BИнтерполяция вставляет строку в текст, а property binding присваивает значение свойству DOM напрямую (сохраняя тип)
CПервое для чисел, второе для строк
DПервое работает только в Chrome
2. Как привязать CSS-класс active к условию isOnline?
A{{ class.active }}
B[class.active]="isOnline"
C(class.active)="isOnline"
D*class="active"