Angular классы с NgClass
С Angular у нас есть много подходов к добавлению, удалению, переключению классов. Мы можем выбрать отдельные классы и связать свойства, или мы можем использовать потрясающую директиву NgClass от Angular.
В этом посте мы рассмотрим привязки классов, а также директиву Angular NgClass, синтаксисы и некоторые передовые идеи.
Часто требуется добавлять какое-то «состояние» в DOM, обычно с помощью классов. Давайте рассмотрим некоторые быстрые и простые варианты, которые у нас есть с Angular.
Связывание свойств с className
Прежде чем мы перейдем к NgClass, давайте рассмотрим простой, но эффективный синтаксис. Работая с отдельными классами, я предпочитаю и поддерживаю этот подход, а не погружаюсь в NgClass, с ним работать быстрее, и я нахожу его более наглядным при анализе существующего кода.
Итак, как это выглядит?
В JavaScript DOM у нас есть свойство className, доступное для элементов DOM:
const div = document.querySelector('div'); div.className = 'hello'; console.log(div.className); // 'hello'
Просто и читаемо. Но в Angular мы работаем с шаблонами и привязками, а не с API-интерфейсами DOM, такими как querySelector.
В Angular мы делаем привязки к свойствам, а не к атрибутам. Это означает, что мы можем превратить этот код в:
<div [className]="'active'"></div>
После этого Angular найдет свойство JavaScript className и свяжет с ним наше выражение.
Для примера возьмите:
<h1>{{ text }}</h1>
В действительности, это синтаксический сахарный для:
<h1 [innerText]="text"></h1>
Теперь давайте все-же вернемся к классам. Возможно, мы хотим добавить тернаное условие в наш className:
<div [className]="condition ? 'active' : 'inactive'"></div>
Имейте в виду, мы не можем сделать подобное сравнение:
<!-- Если условие ложно, в аттрибуте мы получим значение class="false" --> <div [className]="condition && 'active'"></div>
Делаем привязку наших свойств с названием класса
В Angular есть сокращенный синтаксис для установки класса, который мне очень нравится:
<div [class.active]="condition"></div>
Когда перемененная condition равна true, в атрибут class будет добавлено значение active. Если значении равно false, active удаляется из атрибута. Это действительно красиво, чисто и лаконично.
А как насчет более сложных классов, возможно, с использованием синтаксиса BEM (Block-Element-Modifier)?
<div [class.is-active]="condition"></div>
Это все, что нам нужно. К счастью, нам не нужно указывать is-active внутри строки, чего можно ожидать при использовании тире.
Пришло время для NgClass, более гибкого подхода, который я бы использовал, когда нам нужно работать с несколькими классами.
Директива NgClass в Angular
Мы можем использовать NgClass, когда ожидается работа с несколькими классами.
Основной синтаксис NgClass:
string | string[] | Set<string> | { [klass: string]: any }
Это означает, что мы можем предоставить отдельные строки, массивы строк, наборы и литералы объектов. На самом деле, нам больше всего будет интересен объектный литерал, строки и массивы строк позволяют нам устанавливать классы, но не удалять их - потому что нет возможности добавить в них условия, обеспечивающих их существование:
<div [ngClass]="'active'"></div> <div [ngClass]="['active', 'open']"></div>
Итак, давайте исследуем литералы объектов с помощью NgClass:
<div [ngClass]="{ active: condition }"> </div>
Этот пример как и приведенный ваше, устанавливает класс “active” в зависимости от переданного условия.
Однако, обратите внимание, теперь мы не можем задать название класса через тире как в примере ниже, это приведет к ошибке:
<!-- errors --> <div [ngClass]="{ is-active: condition }"> </div>
Почему? Поскольку это литерал объекта, ключи не могут быть установлены с использованием тире без использования строкового синтаксиса. Пример приведенный ниже сработает, так как ключе ‘is-active’ теперь заключен в скобки:
<div [ngClass]="{ 'is-active': condition }"> </div>
Для согласованности синтаксиса я бы вам советовал всегда заключать имена классов в скобки, даже если они не нужны. Это поможет избавится от дальнейших ошибок.
Добавляем несколько классов с NgClass
Пока что мы рассмотрели добавление и удаление отдельных классов с помощью NgClass, поэтому давайте рассмотрим более идеальное решение с несколькими классами.
Также стоит отметить, что condition, которое мы задаем как значение литерального ключа, будет логическим вырожением. Это означает, что мы можем использовать тернарные выражения или выражения отрицать:
<div [ngClass]="{ 'is-active': condition, 'is-inactive': !condition, 'is-focused': condition && anotherCondition, }"> </div>
И так, теперь у вас есть большинство вариантов использования, которые вам когда-либо понадобятся, когда дело доходит до установки классов с помощью NgClass. В целях удобства чтения я бы рекомендовал вам вводить условия в новые строки, как показано выше. Легко искать, читать и оценивать то, что происходит в вашей кодовой базе.