【问题标题】:Router: Redirect from within a promise returned by a `canActivate` method路由器:从“canActivate”方法返回的承诺中重定向
【发布时间】:2016-09-27 09:44:29
【问题描述】:

我有几种方法可以访问我的服务器。所有这些方法都不会返回 Promise 或 observables,我正在传入回调。

现在我需要编写一个守卫,以确保在用户可以使用多个路由之前加载用户数据。 canActivate 方法返回一个 Promise,但在该 Promise 内有代码可以导航,但这是行不通的。

有人知道如何解决这个问题。我是否必须重写我的 api 方法才能返回承诺或 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);
        });
    }
}

【问题讨论】:

    标签: javascript angular angular2-routing


    【解决方案1】:

    以下实施可能很有用。 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: "{"status":false}", status: 200, ok: true, statusText: "OK", 标头:标头...}

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-20
      • 2017-01-28
      • 2020-04-27
      • 1970-01-01
      • 2015-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多