Русский
Русский
English
Статистика
Реклама

Ангуляр

Упрощаем работу с Angular с помощью taiga-uicdk 5 наших лучших практик

11.05.2021 12:14:21 | Автор: admin

CDK базовый пакет библиотеки компонентов Taiga UI. Он не имеет никакой привязки к визуальной составляющей библиотеки, а скорее служит набором полезных инструментов для упрощения создания Angular-приложений.

Среди всех этих инструментов я выделил мою пятерку фаворитов. Я использую их во всех своих проектах и уже давно не представляю, как писать на Angular без них, потому что они ежедневно экономят мне массу времени.

Дисклеймер о весе библиотеки

Перед написанием статьи хотелось бы ответить на вопрос: Для чего тащить в бандл целый мультитул, когда мне нужна пара функций?

По результатам bundlephobia мы получим следующую картинку:

23 КБ результат не самый страшный, но и не очень приятный. Но все сущности наших библиотек лежат в отдельных Secondary Entry Point, что делает их полностью tree shakable. Это значит, что такой объем в бандле мы получим только в случае импорта и использования всех сущностей библиотеки в нашем приложении. Если вы импортите пару сущностей только они и попадут к вам в бандл, добавив к нему в результате меньше 1 КБ.

tuiPure продвинутая мемоизация вычислений

Это декоратор, который можно вешать на геттеры и чистые методы классов. Давайте разберем оба сценария.

Как геттер

Можно повесить декоратор tuiPure на геттер. В таком случае он позволяет сделать отложенные вычисления.

Пример 1. Скрываем и показываем сороковое число Фибоначчи, когда пользователь нажимает на кнопку

// template<div *ngIf="show">fibonacci(40) = {{ fibonacci40 }}</div>// component@tuiPureget fibonacci40(): number {  return calculateFibonacci(40);}

Когда мы запросим число в первый раз, функция посчитает сороковой элемент Фибоначчи. Все последующие запросы будут сразу возвращать ранее посчитанное число.

Пример 2. У нас есть компонент pull to refresh, который эмулирует поведение под iOS и Android. Один из его стримов вызывается только для Андроида, а для iOS нет. Завернем его в getter с pure, и ненужный Observable не будет создан для iOS.

<tui-mobile-ios-loader   *ngIf="isIOS; else angroidLoader"></tui-mobile-ios-loader><ng-template #angroidLoader>   <tui-mobile-android-loader       [style.transform]="loaderTransform$ | async"   ></tui-mobile-android-loader></ng-template>
@tuiPureget loaderTransform$(): Observable<string> {    return this.pulling$.pipe(        map(distance => translateY(Math.min(distance, ANDROID_MAX_DISTANCE))),    );}

Также можно обратиться к changes от ContentChild / ContentChildren: если мы вызываем такой геттер из шаблона, то уже можем быть уверены, что content готов. При соблюдении порядка также это можно провернуть и с ViewChild / ViewChildren.

Как метод

На метод тоже можно повесить декоратор @tuiPure. Тогда он будет работать следующим образом: при первом вызове метода посчитает значение и вернет его. Все последующие вызовы с теми же самыми аргументами будут возвращать уже посчитанный результат. Если аргумент изменится результат пересчитается.

Это полезно не только для сложных вычислений, но и в связке с геттером для создания непримитивов объектов или массивов.

get filteredItems(): readonly string[] {   return this.computeFilteredItems(this.items);}@tuiPureprivate computeFilteredItems(items: readonly string[]): readonly string[] {   return items.filter(someCondition);}

В этом случае можно вызвать геттер из шаблона, один раз отфильтровать items, и он будет возвращать тот же самый массив до тех пор, пока this.itemsне изменится. Это поможет избежать лишних операций пересоздания массива на каждый чих проверки изменений, а также проблем из-за постоянных изменений ссылки на массив при передаче дальше. При этом нам не придется, например, самим синхронизировать состояние в ngOnChanges, если this.items инпут компонента.

Документация по tuiPure

*tuiLet

Это простая структурная директива для объявления локальных переменных в шаблонах.

<ng-container *tuiLet="timer$ | async as time">   <p>Timer value: {{time}}</p>   <p>       It can be used many times:       <tui-badge [value]="time"></tui-badge>   </p>   <p>       It subsribed once and async pipe unsubsribes it after component destroy   </p></ng-container>

Вместо *tuiLetможно использовать *ngIf если вам не нужно показывать шаблон при falsy-значении (или если оно не предусмотрено). Но если вы работаете, например, с числами, то 0, скорее всего, является вполне адекватным значением. Тут и поможет *tuiLet

Документация по tuiLet

Метапайпы tuiMapper и tuiFilter

Мы создали пайп, чтобы не создавать другие пайпы, tuiMapper.

Он очень простой. Это pure-пайп, который принимает в себя чистую функцию для преобразования и произвольное количество аргументов к ней. В шаблоне это выглядит так:

{{value | tuiMapper : mapper : arg1 : arg2 }}

Также удобно и преобразовывать данные для инпутов компонентов в шаблоне или использовать через *ngIf / *tuiLet:

<div    *ngIf="item | tuiMapper : toMarkers : itemIsToday(item) : !!getItemRange(item) as markers"    class="dots">    <div class="dot" [tuiBackground]="markers[0]"></div>    <div        *ngIf="markers.length > 1"        class="dot"        [tuiBackground]="markers[1]"    ></div></div>

Добавление цветных маркеров-точек в календарях @taiga-ui/core

Чистые пайпы кэшируют предыдущее значение и не пересчитываются на каждый цикл проверки изменений, что полностью решает проблемы производительности. А такая передача чистых функций извне позволяет орудовать хендлерами, подменять их или даже передавать в компонент извне. Кроме того, нам не нужно создавать отдельный пайп под каждый кейс, если он нужен нам лишь в одном месте.

А еще у нас есть tuiFilter для удобства фильтрации массивов. Фактически это частный случай маппера, но нам нужен довольно часто. Поскольку это чистый пайп, то никаких проблем с производительностью из-за пересоздания массивов тут нет.

Документация на mapper / документация на filter

destroy$

Это Observable-based сервис, который упрощает процесс отписки в компонентах и директивах.

@Component({   // ...   providers: [TuiDestroyService],})export class TuiDestroyExample {   constructor(     @Inject(TuiDestroyService)      private readonly destroy$: Observable<void>   ) {}   //    subscribeSomething() {       fromEvent(this.element, 'click')           .pipe(takeUntil(this.destroy$))           .subscribe(() => {               console.log('click');           });   }}

Все что нам нужно добавить его в providers компонента и заинжектить в конструкторе. Я предпочитаю писать типы сущностей из DI, которые минимально необходимы в компоненте. Здесь это Observable<void>. Но можно писать и покороче:

constructor(private destroy$: TuiDestroyService) {}

Кстати, сервис в такой ситуации привязывается не к лайфсайклу компонента, а к его DI Injectorу. Это может помочь в ситуации, когда нужно подписаться в сервисе или внутри DI фабрики. Такие кейсы довольно редки, но зато TuiDestroyService в них буквально спасает например, когда мы хотели дергать markForCheck из фабрики токена в статье о DI фокусах для проброса данных.

Ссылка на документацию

Плагины ng-event-plugins

Фактически это внешняя библиотека ng-event-plugins, которая поставляется вместе с cdk (прямая зависимость, которую не нужно устанавливать отдельно). Она добавляет свои обработчики к менеджеру плагинов Angular. В ней есть несколько очень полезных плагинов, которые добавляют ряд возможностей в шаблоны компонентов.

Например, .stopи .preventпозволяют декларативно делать stopPropagation и preventDefault на любой прилетающий ивент.

Было:

<some-input (mousedown)="handle($event)">    Choose date</some-input>
export class SomeComponent {   //    handle(event: MouseEvent) {      event.preventDefault();      event.stopPropagation();      this.onMouseDown(event);   }}

Стало:

<some-input (mousedown.prevent.stop)="onMouseDown()">    Choose date</some-input>

Или модификатор .silent который позволяет не запускать проверку изменений на событие:

<div (mousemove.silent)="onMouseMove()">    Callbacks to mousemove will not trigger change detection</div>

Можно отслеживать ивенты в capture-фазе с помощью .capture:

<div (click.capture.stop)="onClick()">    <div (click)="never()">Clicks will be stopped before reaching this DIV</div></div>

Все это работает и с @HostListenerами, и с кастомными событиями. Вы можете почитать подробнее в документации ng-event-plugins.

Итого

Мы посмотрели ряд сущностей пакета @taiga-ui/cdk. Надеюсь, какие-нибудь из них вам приглянулись и тоже будут помогать во всех дальнейших проектах!

Кстати, у меня еще есть статья про саму библиотеку Taiga UI, в которой описаны остальные пакеты и общая философия библиотеки.

Подробнее..

Angular Moscow Meetup 19 наш митап и там, и тут передают

19.05.2021 12:19:31 | Автор: admin

После длительного перерыва Angular Moscow Meetup наконец вернулся, да еще и в новом гибридном формате! 28 апреля мы собрали в офисе почти 100 человек и еще столько же людей следили за происходящим в прямой трансляции. Мероприятие длилось больше двух часов, мы послушали два доклада и круглый стол с экспертами, среди которых аж три GDE по Angular.

Зрители тоже были полноценными участниками митапа: мы зачитывали их вопросы спикерам, отвечали на комментарии и провели розыгрыш подарков. Кажется, наш эксперимент получился удачным! А в этой статье я расскажу, какие доклады у нас были, дам ссылки на них и фотографии с самого ивента.

Инвертируем зависимости правильно Владимир Агеев, Тинькофф

Владимир показал реальную и довольно хитрую бизнес-задачу, которую он решал со своей командой. Рассказал он и о том, как делать не стоит. В итоге задачу красиво решили с помощью Open-Closed и Dependency Inversion принципов.

Облачный Nx Иван Ишмаметьев, Тинькофф

Иван рассказал об эволюции фронтенда в Тинькофф Бизнес от одной огромной монорепы к многим маленьким монорепам, описав плюсы и минусы каждого подхода.

После он достаточно подробно остановился на Nx, разобрал его преимущества и то, какие проблемы он помог решить. Маствотч для тех, у кого огромные репозитории с долгими билдами на Pull Requestах.

Круглый стол Как не дать Angular-сообществу умереть

Мероприятие завершил круглый стол (хоть и не совсем круглый, и не совсем стол).

На пуфиках расположились лидеры русскоязычного сообщества Angular: Алексей Охрименко, Андрей (Angular Fox) Греков, Александр Инкин, Игорь Кацуба и я между ними. Еще позвали гостем Алексея Корнеева активного драйвера PHP-сообщества.

Тема была немного провокационной, но разговор быстро вышел в позитивное русло. Похоже, Angular-сообщество по-прежнему медленно, но верно процветает. Мы даже пришли к выводу, что и в PHP-сообществе все живенько и хорошо. Посмотрите сами:

Круглый стол переубедил многих слушателей: они думали, что Angular затухает. Сам формат тоже оказался воспринят позитивно будем думать над продолжением и учтем фидбек.

Не расстраивайтесь, если ваш вопрос не попал на стол мы подумаем, как реорганизовать его в более дискуссионный формат в будущем.

Приходите к нам

У нас на постоянной основе открыт Call For Papers. Можно предложить полноценный доклад, лайтнинг доклад на 510 минут или даже просто тему, о которой было бы интересно послушать:

https://github.com/AngularMoscow/Talks/issues/new/choose

Что еще есть

Вот здесь у нас все фотографии с офлайн-ивента: ссылка на VK.

Большое спасибо телеграм-каналам angular_ru и angular_fox за информационную поддержку!

А еще можно подписаться на канал itstinkoff, там регулярно выходят анонсы чего-нибудь нового по Ангуляру.

До новых встреч!

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru