Шаблоны, которые сделают вашу реализацию NgRx чище и понятнее
NgRx - отличная реализация Redux для Angular. Если вы уже реализовали это в проекте, вы, вероятно, заметили, что ваши классы эффектов были слишком большими, у вас было слишком много селекторов, и следить за тем, какой компонент отправляет действие, было не так просто, как должно было быть.
У нас были те же проблемы, поэтому мы придумали несколько шаблонов и архитектурных идей, чтобы решить или хотя бы минимизировать их.
Эти идеи были реализованы в двух масштабных проектах и пользовались большой популярностью у наших разработчиков.
Модуль государственной службы
Я исследовал эту закономерность в течение некоторого времени и зарекомендовал себя в наших проектах. Концепция очень проста - каждый модуль имеет свою собственную службу состояний, и только эта служба состояния имеет доступ к хранилищу.
Использование службы сделает диспетчеризацию действий намного проще и понятнее, потому что вы будете вызывать методы вместо диспетчеризации действий.
Начнем с создания службы состояния приложения. AppStateService
- это корневое состояние, также известное как общее состояние, которое содержит действия и селекторы, относящиеся ко всему приложению.
Затем мы создадим государственную службу для конкретного модуля. Компоненты внутри этого модуля не должны знать о Магазине и взаимодействовать с ним только с помощью этой службы.
В дополнение к использованию государственной службы я предлагаю использовать архитектуру контейнер-компонент и стремиться использовать службу только в контейнерах.
Объединение выборок
Это простой и блестящий фрагмент кода, написанный Офиром Бушинским (אופיר בושינסקי):
Теперь у вас есть единый select
метод для всех свойств состояния (с intellisense, не беспокойтесь…)
this.product$ = this.productStateService.select('product');
Это должно охватывать большинство случаев, но, к сожалению, если вам нужен более сложный селектор, вам все равно нужно его написать.
Класс очищающих эффектов
Вот распространенный метод воздействия:
Обычно у вас будет много методов, подобных этому, и скоро ваш класс Effects будет содержать 300 строк кода.
Чтобы сделать этот класс более читабельным, я предлагаю выделить реализацию в отдельную, максимально чистую функцию. Я бы также создал для этих функций отдельный файл (обычно называю его effects.ts
)
Теперь мы добавим простую вспомогательную функцию:
А наш класс эффектов можно преобразовать в:
Этот рефакторинг также значительно упрощает тестирование ваших эффектов, потому что теперь они являются просто функциями.
Оператор распространения
Оператор Spread (`…`) может использоваться вместо `Object.assign` для создания более чистого кода в редукторах.
return { …state, loading: true }
Подробнее об этом операторе здесь: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals
Более чистая обработка ошибок
Если вы хотите иметь возможность обрабатывать все ошибки с помощью одного и того же обработчика (т.е. регистрировать их), вы можете создать класс с именем ErrorAction, который реализует Action. Затем каждое созданное вами действие при ошибке расширяет его:
Затем перехватите ErrorAction и делайте с ним все, что хотите.
На этом пока все. Я очень надеюсь, что это поможет вам навести порядок в том, что иногда может быть хаосом.
Я хотел бы еще раз поблагодарить Офира за его огромную помощь.
Если у вас есть какие-либо вопросы, комментарии или идеи, не стесняйтесь обращаться ко мне в разделе комментариев или в Twitter (@ TzachOvadia)