获取当前路由组件实例或警卫

时间:2017-03-28 13:59:42

标签: angular angular2-routing

我的导航区域包括我的路由器插座旁边的注销按钮。

app.component.html:

<my-nav-header></my-nav-header>
<router-outlet></router-outlet>

在路由器中的每个模块/组件上,我已经实现了一个用于脏检查的canDeactivate方法(如angular&amp; Naviagtion angular of angular中所述),该方法是通过该教程中描述的接口从实际的canDeactivateGuard调用的。这可以按预期工作 - 当用户单击路由器链接并且有未保存的更改时,系统会询问他是否要进行路由。

MY-NAV-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
  }

当用户按下注销按钮时,我希望在我的注销方法实际将logout命令发送到服务器之前执行脏检查(让用户可以取消注销)。

我尝试将RouterActivatedRoute注入我的导航标题组件,但在这两种情况下,rootConfig属性都为null,导致我无法访问canDeactivate。

所以我的问题是:如何访问当前路由的canDeactivate保护或当前路由组件本身的实例?

2 个答案:

答案 0 :(得分:0)

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;
    }
}

答案 1 :(得分:0)

对于有类似问题的人:虽然这不是我原来问题的真正解决方案(获取当前路线的实例或访问他们的警卫手册),但我可以通过更改订单并使用已退回的承诺来实现我的目标通过router.navigate(...):

@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
          );
        }
      });
  }