使用 canActivate 重定向到 link 时,Angular2+ redirectTo 不起作用

Angular2+ redirectTo not working when redirect to a link with canActivate

当我登录时,redirectTo 无法使用 canActivate 重定向到 link .

redirectTo 在我注销时工作正常,它重定向到我的 /login 组件,并在登录后将 redirectTo 重定向到 /index

但是当我登录时它一直显示 ''

我已将 console.log 添加到我的 authGuard,并且重定向 url“/index”确实进入了那个函数,坚持 '' 情况,没有开发工具崩溃。

但是在评论 canActivate 之后,redirectTo 和以前一样工作正常。

顺便说一下,我的 canActivate 的 authGuard 在其他情况下工作正常(不包括 redirecTo

这是我的应用-routing.module.ts

/* import... */

const appRoutes: Routes = [
    { path: 'login', component: LoginComponent },
    { path: '', redirectTo : '/index', pathMatch: 'full' },
    { path: '**', component: PageNotFoundComponent }
];

/* ngmodel and export ... */

这是我的索引-routing.module.ts

/* import ... */

const indexRoutes: Routes = [
    {
        path: 'index',
        component: IndexComponent,
        canActivate: [AuthGuard], //<- if comment this will work
    },
];

/*   ngmodel and export ... */

这是我的授权-guard.module.ts

/* import ... */

@Injectable()
export class AuthGuard implements CanActivate {
    constructor(
        private authService: AuthService,
        private router: Router
    ) { }
    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        let url: string = state.url;
        //redirectTo did get in here
        console.log(url); //<-- this show /index 

        return this.checkLogin(url);
    }

    checkLogin(url: string): boolean {
        if (this.authService.login_data && (this.authService.login_data.userprofile || !this.authService.login_data.need_login)) {
            return true;
        }
        this.authService.get_login_data()
         .subscribe(
            data => {
                this.authService.login_data = data;
                if (data.userprofile || !data.need_login) {
                    return true;
                }
                this.authService.redirectUrl = url;
                this.router.navigate(['/login']);
                return false;
            },
            error => { this.authService.errMsg = <any>error;}
        );
    }
}

顺便说一句,我已经将我的项目更新为 angular4.0.1

谢谢。

更新:

我已经将我的守卫 return 从布尔值更改为可观察值

但是还是不行。

这是我用过的代码。

    checkLogin(url: string): Observable<boolean> {
        if (this.authService.login_data && (this.authService.login_data.userprofile || !this.authService.login_data.need_login)) {
            console.log('gonna return observable true');
            return Observable.of(true);
            //return true;
        }
        this.authService.get_login_data()
        .subscribe(
            data => {
                this.authService.login_data = data;
                if (data.userprofile || !data.need_login) {
                    console.log('in subscribe and gonna return observable true');
                    return Observable.of(true);
                    //return true;
                }
                this.authService.redirectUrl = url;
                this.router.navigate(['/login']);
                return Observable.of(false);
                //return false;
            },
            error => { this.authService.errMsg = <any>error;}
        );
    }

在我的控制台中,我得到了 in subscribe and gonna return observable true

更新:

检查后检查此

问题可能是canActivate没有等到订阅结束

在你AuthGuardcheckLogin():

checkLogin(url: string): boolean {
    if (this.authService.login_data && (this.authService.login_data.userprofile || !this.authService.login_data.need_login)) {
        return true;
    }
    this.authService.get_login_data()
     .subscribe(
        data => {
            this.authService.login_data = data;
            if (data.userprofile || !data.need_login) {
                return true;
            }
            this.authService.redirectUrl = url;
            this.router.navigate(['/login']);
            return false;
        },
        error => { this.authService.errMsg = <any>error;}
    );
}

它的return类型是布尔值,它return真,在某些情况下,它是可以的。但是,后面的部分有一些问题。在您订阅结果并根据该结果 return 之前,您没有 return 任何东西。

这意味着,此函数将 return 未定义,因此 canActivate 检查将不起作用。

[更新]你想从结果中设置用户数据,你应该在你的 authService.get_login_data() 中使用 do() 来设置它。当您订阅结果时,将调用此 'do' 函数。在您的 checkLogin() 中使用 .map() 而不是 subscribe() 将登录结果数据映射到布尔值。

在这种情况下,您应该 return 一个 Observable 类型,例如:

checkLogin(url: string): Observable<boolean> {
if (this.authService.login_data && (this.authService.login_data.userprofile || !this.authService.login_data.need_login)) {
    return Observable.of(true); // wrap true in Observable
}
return this.authService.get_login_data()
 .map(
    data => {
        if (data.userprofile || !data.need_login) {
            return true;
        }
        this.authService.redirectUrl = url;
        this.router.navigate(['/login']);
        return false;
    },
    error => { this.authService.errMsg = <any>error;}
);

}

我已经通过更改订阅地图解决了我的问题。

这是我编辑后的代码。

checkLogin(url: string): Observable<boolean>|boolean {
    if (this.authService.login_data && (this.authService.login_data.userprofile || !this.authService.login_data.need_login)) {
        console.log('gonna return observable true');
        return Observable.of(true);
    }   
    return this.authService.get_login_data()
    .map(
        data => {
            this.authService.login_data = data;
            if (data.userprofile || !data.need_login) {
                console.log('in subscribe and gonna return observable true');
                //return Observable.of(true);
                return true;                                                                                                                                                
            }   
            this.authService.redirectUrl = url;
            this.router.navigate(['/login']);
            //return Observable.of(false);
            return false;
        },  
        error => { this.authService.errMsg = <any>error;}
    );  
}  

在地图中,如果我 return Observable(true)

Type 'Observable<Observable<boolean>>' is not assignable to type 'boolean | Observable<boolean>'.

感谢您的帮助和建议。