2016-09-27 41 views
1

我有幾種訪問我的服務器的方法。所有這些方法都不會返回promise或observables,我將回調函數傳遞進去。路由器:從`canActivate`方法返回的許諾內重定向

現在我需要編寫一個保護程序,它可以確保在用戶可以使用多個路由之前加載了用戶數據。 canActivate方法返回一個承諾,但是有一些代碼可以在該承諾中導航,但不起作用。

有沒有人知道如何解決這個問題。我是否必須重寫我的api方法以返回promise或obervables?或者有沒有辦法使用承諾進行重定向,即返回我的canActivate。將代碼移動到獲取用戶數據(如果用戶登錄)到解析對象中會更好嗎?

import {Injectable} from '@angular/core'; 
import {CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router'; 
import {GlobalStateService} from './globalState.service'; 
import {AuthTokenService} from './authToken.service'; 
import {UserApi} from '../api/user.api'; 

@Injectable() 
export class AfterLogInGuardService implements CanActivate { 

    constructor(
     private globalState: GlobalStateService, 
     private authToken: AuthTokenService, 
     private router: Router, 
     private userApi: UserApi 
    ) { } 

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean|Promise<boolean> { 

     // The tho user is not logged in, redirect her always to the login page, if 
     // she calls routes with this guard. 
     if (!this.authToken.has()) { 
      this.router.navigateByUrl('/logIn'); 
      return false; 
     } 

     const thisGuard = this; 

     // If the user has a token, we have to ensure, that we have the user data 
     // loaded from the server. 
     return this.afterUserDataHasBeenLoaded(function() { 

      // Redirect the user to the "Please enter your personal data" page, if 
      // she has not entered them yet. 
      if (!thisGuard.globalState.personalDataStored && route.url.toString() !== 'signUp,personalData') { 

       // 
       // This here doesn't work! 
       // 

       thisGuard.router.navigateByUrl('/signUp/personalData'); 
       return false; 
      } 
      return true; 
     }); 
    }; 

    private afterUserDataHasBeenLoaded(callback:() => boolean) { 

     const thisGuard = this; 

     return new Promise<boolean>(function(resolve, reject) { 

      if (thisGuard.globalState.userDataLoaded) 
       return callback(); 

      const innerCallback = function() { 
       thisGuard.globalState.userDataLoaded = true; 
       resolve(callback()); 
      }; 

      thisGuard.userApi.getUserData(innerCallback); 
     }); 
    } 
} 

回答

0

以下實施可能有用。承諾在auth.service定義

auth.guard

import { Injectable } from '@angular/core'; 
import { Router, CanActivate } from '@angular/router'; 
import { AuthService} from './services/auth.service'; 

@Injectable() 
export class AuthGuard implements CanActivate { 
     status:boolean=false; 
     constructor(private authService:AuthService, private router:Router) { } 
     canActivate() { 
     var self=this; 
     this.authService.isAuth() 
     .then((res)=>{if(res==true)return true;else self.router.navigate(['/login']);}); 
     } 
    } 

auth.service

isAuth(): Promise<Status> { 
    const url = "/account/check"; 
    return this.http.get(url) 
    .toPromise() 
    .then(response=>return response.json().status as Status) 
    .catch(this.handleError); 
} 

服務器響應

{_body:「{ 「statu s「:false}」,狀態:200,ok:true,statusText:「OK」, 標題:標題...}