Подписка на наблюдаемые в маршрутных охранниках и их последствия
У меня охранник роутера называется PermissionGuard
который начинается здесь
const routes: Routes = [
{
path: ':company',
component: CompanyComponent,
canActivate: [PermissionGuard],
canActivateChild: [PermissionGuard],
children: [
{
path: '',
component: IndexComponent
},
{
path: 'projects',
loadChildren: '../projects/projects.module#ProjectsModule'
},
]
}
];
Внутри моего PermissionGuard
Я подписываюсь на PermissionService
как это:
export class PermissionGuard implements CanActivate, CanActivateChild {
private permissions: Permission[];
constructor(private permissionService: PermissionService, private router: Router) {
this.permissionService.permissions$.subscribe(
(permissions: Permission[]) => {
this.permissions = permissions;
}
);
}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
this.permissionService.getPermissions(next.paramMap.get('company'));
return this.permissionService.permissionsFetchDone$
.pipe(filter(x => x))
.pipe(
map(response => {
if (this.permissions) {
return true;
} else {
this.router.navigate(['/forbidden']);
}
})
);
}
}
и выполнить необходимое canActivate
или же canActivateChild
проверки на основе этих данных. От добавления console.log()
и испуская новые данные из permissions$
внутри детских маршрутов я вижу, что наблюдаемая все еще активна, хотя охрана "использовалась" и маршрут активирован. Затем я ожидал, что он исчезнет, когда я пойду на маршрут за пределами path: ':company'
Однако охранник не уничтожен.
Это подводит меня к моему вопросу: правильно ли я делаю? Я хочу использовать охрану, чтобы проверить, есть ли у пользователя какие-либо разрешения, но в то же время я хочу выполнить HTTP-запрос на разрешения только один раз (при переходе к path: ':company'
или любой из его детей). Я боюсь, что если я буду использовать такие охранники, это со временем замедлит все приложение из-за огромного количества наблюдателей.
1 ответ
испуская новые данные из прав доступа $ внутри дочерних маршрутов, я вижу, что наблюдаемая все еще активна, даже если охрана "использовалась" и маршрут активирован.
Прежде всего, permissions$
все еще активен, потому что вы никогда не отписались в своей охране. И угловой создает охрану как синглтон.
Даже если охранник не был одиночкой, на экземпляр охранника все еще ссылаются в подписке через this.permissions
и если ваша наблюдаемая существует как переменная в вашей службе аутентификации (которую я предполагаю, что она является одиночной), эта привязка также предотвратит сборку мусора.
Это подводит меня к моему вопросу: правильно ли я делаю? Я хочу использовать охрану, чтобы проверить, есть ли у пользователя какие-либо разрешения,
Вполне нормально подать запрос в вашей гвардии, например, для получения разрешений.
но в то же время я хочу выполнить HTTP-запрос на разрешения только один раз (при переходе к пути: ':company' или любому из его дочерних элементов).
Если вы хотите выполнить запрос только один раз, вам следует подумать об использовании shareReplay в вашей службе аутентификации, чтобы все будущие экземпляры, которые подключаются, использовали одинаковые ранее выданные значения.