Получить текущий экземпляр компонента маршрута или охранников

У меня есть область навигации, включая кнопку выхода из системы, рядом с моей розеткой маршрутизатора.

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;
    }
}
Другие вопросы по тегам