2016-09-27 5 views
1

У меня есть несколько способов доступа к моему серверу. Все эти методы не возвращают обещаний или наблюдаемых, я передаю обратные вызовы.Маршрутизатор: переадресовать из обещания, возвращенного методом `canActivate`

Теперь мне нужно написать охранник, который гарантирует, что пользовательские данные были загружены до того, как пользователь сможет использовать несколько маршрутов. Метод canActivate возвращает обещание, но есть код для навигации в рамках этого обещания, и это не работает.

Есть ли у кого-нибудь идея, как это исправить. Должен ли я переписывать свои api-методы для возврата обещаний или обвинений? Или есть способ сделать переадресацию с обещанием, которое возвращается моим 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

Последующая реализация может быть полезна. Promise определяется в 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", заголовки: заголовки ...}

Смежные вопросы