Resolver или Guard - который больше подходит для извлечения данных с помощью ngrx - PullRequest
1 голос
/ 22 марта 2019

Используя Angular и ngrx, я хочу перейти к маршруту и ​​убедиться, что необходимые данные доступны в ngrx / store. Я использую действие / эффект / редуктор ngrx / store для физического вызова API. Компонент, который загружает маршрут, обращается к данным через хранилище, так как другие части системы могут обновлять данные.

Если данные не загружаются, отправляется действие LOAD_FAILED, которое может быть обработано различными способами.

Должен ли я использовать охрану или распознаватель? Каковы некоторые другие плюсы и минусы каждого подхода? Что вы пробовали, и если бы у вас было время снова, вы бы сделали это так же? Ниже приведены некоторые из моих мыслей.

Вариант 1: Охрана

При доступе к маршруту canActivate охранника проверяет, есть ли данные в хранилище, а если нет, загружает их из API и добавляет их в хранилище. Если данные не загружаются, canActivate возвращает false (как наблюдаемое).

У этого подхода есть обратная сторона: «загрузка данных не должна быть обязанностью охранника», но есть и проблема предотвращения доступа, если данные не могут быть загружены, и маршрутизатор может обработать переход к «не найден», оба из которых находятся в пределах ответственности.

Вариант 2: резольвер

При доступе к маршруту и ​​разрешению активации любых других охранников вызывается распознаватель. Этот распознаватель проверяет, находятся ли данные в хранилище, и, если нет, запускает действие LOAD, чтобы загрузить из API и добавить в хранилище. Затем, как только данные были загружены, распознаватель возвращает некоторые произвольные данные, которые отбрасываются маршрутом / компонентом, поскольку компонент использует хранилище. Если данные не загружаются, что-то будет перенаправлено на не найденную страницу

У этого подхода есть и обратная сторона: распознаватель не используется в традиционном смысле, например данные, которые он возвращает, отбрасываются. Кроме того, либо преобразователь должен перенаправить на 404, когда не найден, или LOAD_FAILED необходимо перенаправить. Это добавляет сложности, поскольку могут быть случаи, когда LOAD_FAILED не должен перенаправлять, например, когда фоновое действие запускает загрузку. С другой стороны, за загрузку данных отвечает распознаватель.

1 Ответ

1 голос
/ 10 апреля 2019

В моем проекте мы используем хранилище NgRx, и мы используем Guards для получения данных. У этого подхода есть свои плюсы и минусы, но, с моей точки зрения, резольверы не очень подходят для этого типа обработки данных, и в Angular отсутствует какой-то дополнительный класс, такой как PreloadingGuard (или аналогичный), что-то, что могло бы находиться между защитником. и resolver - будет отвечать за выборку данных, но не будет получать доступ к маршруту. Перечислим минусы и плюсы:

Минусы:

  • извлечение данных не является обязанностью гвардии, это противоречит их определению

Плюсы:

  • Данные должны храниться в хранилище до того, как перенаправление действительно будет выполнено - это «обязательно». Можно было бы сказать, что мы могли бы использовать * ngIf в верхней части компонента, но это выглядит странно с точки зрения конечного пользователя: вы находитесь на странице A, нажимаете кнопку, затем страница становится белой (плюс, возможно, какой-то блесна сверху), внезапно появляется контент, и вы на странице B. С охраной у нас нет части «белой страницы» - все гладко и красиво.

  • Если используется охранник и ему не удалось получить данные - пользователь не перенаправлен на другой маршрут, он / она остается на прежнем месте. Сделайте то же самое с решателем - и пользователь зависает где-то посередине, потому что он уже переместил его на другой маршрут, и нам нужен дополнительный код, чтобы переместить его туда, где он только что был.

  • Обычно вам нужен эффект для асинхронной выборки данных. Вы должны написать такие действия, как LoadSth, LoadSthSuccess, LoadSthError. С защитой вам не нужен эффект, и вам не нужны 3 действия (достаточно LoadSthSuccess). Вы можете позвонить в службу безопасности и затем отправить действие LoadSthSuccess. Лично я использую Эффект только тогда, когда мне нужно - эти звери хитры, и я настоятельно рекомендую избегать их использования как можно чаще. Охранники - просто лучшая замена.

  • Обработка ошибок намного лучше с Guards. По сути, вы не хотите, чтобы пользователь видел поврежденную страницу (с неполными данными). Охранники помогут вам добиться этого - отобразить модальное сообщение об ошибке и вернуть Observable.of (false) от охранника + остаться на предыдущем просмотре

  • Вы можете использовать один и тот же сторож в нескольких местах и ​​получать данные ТОЛЬКО, когда состояние пусто - поэтому вы уверены, что загружаете данные только один раз, и вы уверены, что они действительно были загружены при доступе к определенному маршруту.

...