Я решил написать статью о десяти приемах, которые набрали больше всего лайков, а также объяснить показанные в них концепции более подробно.
Давайте начнем!

Токенизируй глобальные объекты!
Самый популярный твит рассказывает о DI-токенах глобальных объектов.
Во фронтенде мы привыкли к тому, что в глобальном окружении есть множество объектов. Мы используем объекты вроде window, document, fetch-метод, location и никогда не ожидаем, что их может и не быть.
Но, к примеру, в Angular Universal или тестовом окружении в Jest нет ни браузера, ни window-объекта, ни DOM. А передавая эти сущности по приложению через токены, у вас никогда не будет проблем с их использованием, заменой или тестированием вашего кода.
#AngularTip for the day! You can tokenize global objects to use them with #angular Dependency Injection. It allows you to make your entities more abstract and easy to replace and test
By the way, we have all the basic tokens in our library: https://t.co/zPMj3orUpT pic.twitter.com/D3S6qCrvyE
— Roman Sedov (@marsibarsi) June 21, 2020
Наследование от Observable или Subject
Я знаю многих разработчиков, которые создают хорошие сервисы в своих приложениях. Эти сервисы делают одно дело хорошо. И, поскольку в Angular экосистеме мы используем RxJS, такие сервисы могут содержать только одно поле с Observable или Subject внутри себя для преобразования данных.
Такие ситуации можно упростить, наследуя сервисы от Observable или Subject:
#AngularTip for the day! Do not forget that your #angular services can extend Observable. It is just a class
Read more about how we use it in Web APIs for Angular here: https://t.co/PZyXR5fk5I
And take a look at this sample of GeolocationService implementation pic.twitter.com/sfLX5kSUF9
— Roman Sedov (@marsibarsi) June 20, 2020
Control value как ReplaySubject
Могут быть ситуации, когда необходимо подписаться на valueChanges реактивного контрола, начав стрим с его текущего значения. Теперь можно не изобретать велосипед, а просто добавить к себе такую обертку:
#AngularTip for the day! You can turn your #angular AbstractControl / AbstractControlDirective valueChanges into ReplaySubject(1) with a simple wrapper
Gist to copy: https://t.co/HO3vGvND9D pic.twitter.com/RcOpNo9MTM
— Roman Sedov (@marsibarsi) June 6, 2020
Делаем приложение лучше для High DPI дисплеев
Известно ли вам, что вы можете легко отслеживать юзеров с High DPI экранами?
Более того, вы можете даже предоставлять для таких мониторов медиаэлементы подходящего разрешения с помощью нативного media-тега и без дополнительных усилий:
#AngularTip for the day! You can make an #angular structural directive for adding content only if the user has High DPI display
It is convenient to use with video or picture sources pic.twitter.com/ejNeENGoyI
— Roman Sedov (@marsibarsi) June 17, 2020
Не забывайте о пайпах
Пайпы — отличный инструмент для работы в стиле фреймворка Angular. Они позволяют нам оставаться в рамках декларативного подхода внутри шаблонов наших компонентов. Печально, что некоторые разработчики на Angular избегают создания своих собственных пайпов: с ними можно аккуратно преобразовать данные почти в любой ситуации.
А вот пример универсального пайпа для преобразования данных:
#AngularTip for the day! Make a simple #angular mapper pipe that transforms value in a template with pure functions. Here is a well-typed sample by me
️This way Angular runs change detection only when mapper parameters have changed
Stackblitz demo:https://t.co/C5ddi9GQu4 pic.twitter.com/i7vhJnYtGz
— Roman Sedov (@marsibarsi) June 10, 2020
Сделайте свой ящик с бананом
У этой Angular-фичи много названий: banana-in-a-box, two-way binding или просто input-output. Обычно этот подход встречают в формах, работая с [(ngModel)]. Но знаете ли вы, как реализовать это для своих собственных компонентов?
#AngularTip for the day! Do you know that you can make «Banana in a box» input-output in your Angular component?
Just add «Change» postfix for the output name: pic.twitter.com/mxkrR455XT
— Roman Sedov (@marsibarsi) July 16, 2020
RxJS — неизведанный мир
Я всегда стараюсь проверять все параметры и перегрузки у RxJS-операторов, которые использую. Причина: во многих из них есть скрытые опции, узнав которые можно писать некоторые стримы быстрее и проще.
Кроме того, бывают еще и непопулярные операторы. Они редко попадаются, но могут решить некоторые конкретные проблемы в одну строчку кода вместо огромного и хитрого стрима.
Например, одним из таких открытий для меня стала функция сравнения в distinctUntilChanged-операторе:
#AngularTip for the day! #rxjs has many useful details, do not forget to check all parameters of rxjs operators.
For example, did you know that you can use your own «compare» function into distinctUntilChanged operator? pic.twitter.com/5ldGEcHVrX
— Roman Sedov (@marsibarsi) June 27, 2020
А был еще такой популярный твит о RxJS. Маленькая хитрость, чтобы сделать свои компоненты капельку проще расширяемыми:
#AngularTip and #rxjsTip for the day! it is a good practice to make subjects private in public API and to provide an observable for class users.
You can use .pipe() instead of .asObservable(). The result is the same but .pipe() is more easy to expand in the future pic.twitter.com/LqFNf4gjjB
— Roman Sedov (@marsibarsi) June 30, 2020
Или оператор defaultIfEmpty, который позволяет заложить полезную логику в стрим в рамках одной строчки кода:
#AngularTip and #rxjsTip for the day! it is a good practice to make subjects private in public API and to provide an observable for class users.
You can use .pipe() instead of .asObservable(). The result is the same but .pipe() is more easy to expand in the future pic.twitter.com/LqFNf4gjjB
— Roman Sedov (@marsibarsi) June 30, 2020
Можно даже написать собственную альтернативу ngFor
И последнее: в Angular есть специальный синтаксис для селекторов директив наподобие for … of … С его помощью можно создать собственный ngFor под любую вашу задачу.
Например, можно сделать быстрый ngFor для перебора объекта Map. Или вот такой, простой for для итерации индекса от одного числа до другого:
#AngularTip for the day! You can make an #angular directive similar to ngFor but using a number of repetitions rather than an array
It can save your time creating calendars, pagination or anything else you need to repeat a certain number of timeshttps://t.co/0qtKJUzGVM pic.twitter.com/GsJ6MDOiKY
— Roman Sedov (@marsibarsi) June 9, 2020
Заключение
Angular большой, и в нем еще множество фишек. У меня есть ряд идей для новых приемов и хитростей из наших лучших практик, которыми я планирую поделиться с сообществом. Если вам интересны подобные новые твиты, подписывайтесь на меня в Твиттере. И хорошего вам дня!