Получить текущий экземпляр компонента маршрута или охранников
У меня есть область навигации, включая кнопку выхода из системы, рядом с моей розеткой маршрутизатора.
app.component.html:
<my-nav-header></my-nav-header>
<router-outlet></router-outlet>
На каждом модуле / компоненте в маршрутизаторе я реализовал метод canDeactivate для грязной проверки (как описано в учебнике по угловым маршрутам и навигации), который вызывается из фактического canDeactivateGuard через интерфейс, как описано в этом учебном пособии. Это работает, как и ожидалось - когда пользователь щелкает ссылку на маршрутизатор и имеет несохраненные изменения, его спрашивают, следует ли в любом случае выполнить маршрутизацию или нет.
мой-нав-header.component.ts
logoutBtnClick(){
// todo: insert call to canDeactivate here
// or find another way to get dirty state of current component in router
//console.debug('logout - can deactivate[1]: ', this.activatedRoute.routeConfig.canDeactivate);
//console.debug('logout - can deactivate[2]: ', this.activatedRoute.snapshot.routeConfig.canDeactivate);
this.loginSvc.doLogout();
}
login.service.ts
@Injectable()
export class LoginService {
...
public doLogout(){
this.myHttp.sendLogout().subscribe(
()=> {
this.clearSessionData();
this.myHttp.clearSessionData();
this.router.navigate(['/login']); // triggering canDeactivate, but too late as logout command already has been sent to the server
}
Когда пользователь нажимает кнопку выхода из системы, я хочу выполнить грязную проверку (предоставляя пользователю возможность отменить выход из системы), прежде чем мой метод выхода из системы фактически отправит команду выхода из системы на сервер.
Я пытался ввести оба Router
а также ActivatedRoute
в мой компонент заголовка навигации, но в обоих случаях свойство rootConfig имеет значение null, что не позволяет мне получить доступ к canDeactivate.
Итак, мой вопрос: как получить доступ к canDeactivate guard текущего маршрута или к экземпляру самого текущего компонента маршрута?
2 ответа
Для тех, у кого есть похожие проблемы: хотя это не является реальным решением для моего первоначального вопроса (получить экземпляр текущего маршрута или получить доступ к руководству по их охране), я мог бы достичь своей цели, изменив порядок и воспользовавшись обещанием, возвращаемым маршрутизатором. навигации (...):
@Injectable()
export class LoginService {
...
public doLogout(){
this.router.navigate(['/login'])
.then((routerNavigationResult: boolean)=> {
if (routerNavigationResult) {
// only when the navigation is allowed, i.e. no change or change disccarded
this.myHttp.sendLogout().subscribe(
(data) => this.clearSessionData(),
(error) => this.handleLogoutError(error) // in my case also clears session data
);
}
});
}
CanDeactivate
Класс принимает тип компонента, который он проверяет. Определив интерфейс для компонента, который имеет метод canDeactivate, вы можете проверить, существует ли метод, и условно вызвать его в активном компоненте, если он реализует метод. В противном случае вы можете вернуть true и разрешить деактивацию компонента;
interface ICanComponentDeactivate extends Component {
canDeactivate: () => Observable<boolean> | boolean;
}
export class CanDeactivateGuard implements CanDeactivate<ICanComponentDeactivate> {
public canDeactivate(currentComponent: ICanComponentDeactivate,
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | boolean {
return currentComponent.canDeactivate ? currentComponent.canDeactivate() : true;
}
}