Guards¶
Guards позволяют ограничить навигацию по определенным маршрутам. Например, если для доступа к определенному ресурсу требуется наличие аутентификации или наличие каких-то других условий, в зависимости от которых мы можем предоставить пользователю доступ, а можем и не предоставить. То есть guards защищают доступ к ресурсу, собственно поэтому данные элементы и названы так: "guards", что с английского можно перевести как "защитники".
CanActivate¶
CanActivate представляет один из типов guards, который позволяет управлять доступом к ресурсу при маршрутизации. Так, возьмем для примера базовый проект приложения:
Добавим в папку src/app для примера пару компонентов. Первый компонент поместим в файл home.component.ts:
1 2 3 4 5 6 7 | |
И также добавим файл about.component.ts:
1 2 3 4 5 6 7 | |
Допустим, мы хотим ограничить доступ к компоненту AboutComponent. Для этого добавим в папку src/app новый файл about.guard.ts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Класс AboutGuard реализует интерфейс CanActivate, а именно его метод canActivate(). Этот метод получает два параметра — объекты ActivatedRouteSnapshot и RouterStateSnapshot, которые содержат информацию о запросе. ActivatedRouteSnapshot позволяет получить различную информацию из запроса, в том числе параметры маршрута и строки запроса. Например, если бы в маршруте использовался параметр id, то мы могли бы его здесь получить:
1 2 3 4 5 6 7 | |
Результат метода — логическое значение, либо логическое значение, обернутое в объект Observable. Если AboutGuard разрешает переход, то метод canActivate() должен возвращать true. Если доступ запрещен, то метод возвращает false.
Для тестирования обоих ситуаций здесь вызывается метод confirm(), который отображает диалоговое окно с выбором. Если пользователь нажмет на кнопку отмены, то метод confirm возвратит false. Если же пользователь подтвердит действие, то будет возвращено значение true.
Определим в файле app.component.ts ссылки для перехода к компонентам:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
А в главном модуле приложения установим маршруты:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | |
Чтобы ограничить доступ по маршруту /about, в определении этого маршрута прописывается параметр canActivate: [AboutGuard].
Кроме того, AboutGuard должен быть указан в списке провайдеров модуля:
1 | |
В итоге при попытке перехода по маршруту /about, отобразится диалоговое окно с подтверждением перехода.
CanDeactivate¶
CanDeactivate также позволяет управлять переходами. Он предназначен для таких, к примеру, случаев когда пользователь вводит какие-то данные. Однако не сохраняет их и покидает страницу. В этом случае мы могли бы выдать пользователю какое-либо предупреждение или окно с подтверждением перехода, чтобы избежать потери введенных данных.
То есть, если сравнивать с CanActivate, CanActivate проверяет возможность перехода на определенный компонент, а CanDeactivate проверяет возможность ухода с определенного компонента.
Для примера добавим в папку src/app новый файл exit.about.guard.ts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
ExitAboutGuard должен реализовать метод canDeactivate() интерфейса CanDeactivate. Этот метод собственно и управляет уходом с компонента и переходом на другой компонент.
Для управления навигацией в этот метод передается компонент, с которого осуществляется переход. Благодаря этому мы можем учитывать состояние компонента при переходе. Но передаваемый параметр должен реализовать определенный интерфейс — в данном случае ComponentCanDeactivate. Выше определен этот интерфейс:
1 2 3 | |
Название интерфейса не столь важно, главное, чтобы он определял метод canDeactivate(), который возвращает объект boolean | Observable<boolean>. Если нельзя осуществить переход, то возвращается значение false, иначе возвращается значение true. Это может быть просто логическое значение, либо же логическое значение, обернутое в объект Observable.
Допустим, мы хотим управлять навигацией с компонента AboutComponent. В этом случае класс AboutComponent должен реализовать интерфейс ComponentCanDeactivate:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
Для имитации функционала в класс AboutComponent добавлено свойство saved, которое указывает, сохранены ли данные. С помощью метода save(), который вызывается по нажатию на кнопку, мы можем управлять значением этой переменной. К примеру, нажали на кнопку, значит данные сохранены, и свойство saved равно true.
Далее в классе AboutComponent реализуем метод canDeactivate(). Этот метод и будет вызываться в ExitAboutGuard. Поэтому в этом методе мы можем проверить состояние компонента и решить, стоит ли делать переход, надо ли выполнить какие-то дополнительные действия и т. д.
В данном случае, если this.saved == false (то есть условно, если данные не сохранены), то выводим диалоговое окно для подтверждения действия.
Чтобы задействовать ExitAboutGuard, изменим модуль AppModule:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | |
Во-первых, в определении маршрута добавляется параметр
1 | |
Во-вторых, сам класс ExitAboutGuard добавляется в список провайдеров:
1 | |
И теперь при попытки ухода с компонента AboutComponent (если saved == false), мы увидим диалоговое окно для подтверждения перехода:


