Создание переменных в шаблонах Angular. Превращение реактивных свойств в простые объекты.
В данной статье поговорим о создании переменных в шаблонах Angular компонент, а также поговорим о трюках связанных с использованием реактивных свойств.
В основной документации Angular мало говориться о компонентах и создании шабловнов внутри компонент. Но данной документации недостаточно, так как не раскрывает проблемы и их решения, появляющиеся в процессе верстки.
Одной из основных проблем является работа с реактивными (Observable) переменными.
Допустим есть сервис, где одно свойство является реактивным:
И есть компонент, в шаблоне которого нужно вывести в двух местах:
И как видно из шаблона, уже идет достаточно громоздкое дублирование кода.
Плохой подход для создания переменных
Плохим решением будет создание обычной переменной в TS компоненте с помощи подписки:
Хоть и выглядит это не так страшно, но так вы сделать не можете. Нужно добавить отписку.
Уже выглядит заметно хуже.
Данный подход плох:
- Нужно создавать подписки/отписки
- Добавляется неиспользуемая переменная в компоненте
- Раздувание компонента и необходимость тестирования ненужного кода
Если в пример добавить еще 4 сервиса и будет вообще ужас, который поддерживать будет почти невозможно.
Теперь поговорим о правильных подходах создания переменных.
Правильное создание переменных
Первым решением может быть *ngIf
Результат ngIf можно превратить в динамическую переменную:
Однако данное решение будет работать не всегда. Например, если значение реактивной переменной является boolean = false. Но даже если это объект, это не решает проблему с использованием двух и более переменных.
Добавим ещё один сервис:
Добавим в компонент и выведем данные из добавленного сервиса:
И так вроде нормально, но что будет если нужно будет использовать данные из сервисов одновременно?
Как не сложно догадаться, в ходе роста проекта, все это будет расти:
Вторым и более надёжным решением является NgTemplateOutlet.
Данная структурная директива помогает разбить базовый шаблон компонента на множество маленьких, в которые можно пробросить пользовательские переменные.
Перепишем последний пример на NgTemplateOutlet:
Выглядит так себе, но с точки кода и функциональности это просто огонь.
Формально мы превратили все реактивные свойства в обычные!
Принцип NgTemplateOutlet очень прост. Директива принимает 2 аргумента:
- имя шаблона, в котором нужно отобразить данные,
- объект context, с помощью которого и будут переданы значения.
Для того, чтобы обратиться к переменной нужно объявить её в <ng-template>
, добавив аттрибут let
и через тире указать имя.
Отметим, что в данном случае мы передаём только реактивны свойства, но там также могут быть любые значения. Например, сокращения для доступа в сложных объектах.
Передача переменных в компонент
Но что можно делать ещё?
Одной и самых частых задач в данном подходе это необходимость использования переменной внутри компонента.
Она решается очень легко, просто оборачивая Observable:
Как можно заметить, теперь мы обращаемся не к свойству сервиса, а к нашей обёртке над ним.
Наблюдатели и слушатели в компоненте
Ещё одной популярной задачей является создание слушателей.
Они создаются аналогично предыдущему решению:
Ожидание загрузки всех данных
Последней часто встречающейся задачей является ожидание загрузки всех данных.
Как предыдущие решения реализуется очень просто с помощью оператора combineLast:
Конечно, можно сохранить данные из пред загрузки, но это остаётся на усмотрение читателя.
Резюме
В данной статье рассмотрели проблемы связанные с созданием и управлением переменных. Был приведён пример плохого использования подписок, для получения доступа к значению реактивных переменных.
В качестве решения проблемы создания переменных было предложено два подхода:
- создание переменной с помощью *ngIf
- создание множественных переменных с помощью *ngTemplateOutlet
В конце статьи рассмотрели порулярные задачи, связанные с работой с реактивными переменными и привели решения наиболее часто встречающихся задач:
- Создание переменной в компоненте
- Создание наблюдателя
- Создание прелоадера
Спасибо за внимание!
Подписывайтесь на канал, чтобы не пропустить новые статьи про Angular и мира фронтенд разработки.
Предыдущие статьи: