【问题标题】:Angular2+ redirectTo not working when redirect to a link with canActivate使用 canActivate 重定向到链接时,Angular2+ redirectTo 不起作用
【发布时间】:2017-05-12 03:47:30
【问题描述】:

当我登录时,redirectTo 无法重定向到带有canActivate 的链接 .

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

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

我已将console.log 添加到我的authGuard 中,并且重定向网址“/index”确实进入了该功能,在坚持'' 的情况下,开发工具没有崩溃。

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

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

这是我的 app-routing.module.ts

/* import... */

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

/* ngmodel and export ... */

这是我的 index-routing.module.ts

/* import ... */

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

/*   ngmodel and export ... */

这是我的 auth-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

谢谢。

更新:

我已将我的后卫返回值从布尔值更改为 Observable

但还是不行。

这是我使用的代码。

    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

更新:

检查后检查后

AuthGuard doesn't wait for authentication to finish before checking user

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

【问题讨论】:

  • 这是我的第一个问题。阅读后我会做得更好。谢谢。
  • 你遇到了什么错误?
  • 没有错误,但它不起作用。

标签: angular typescript router


【解决方案1】:

在你 checkLogin()AuthGuard 中:

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

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

也就是说,这个函数会返回undefined,所以canActivate检查不起作用。

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

在这种情况下,你应该返回一个 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;}
);

}

【讨论】:

  • .subscribe() 不返回Observable。它返回一个Subscription,这当然是这里真正的问题。
  • 我更改了代码使其返回 Observable(true);但它仍然不起作用。如果订阅是问题,有什么想法可以确保我可以在从服务器返回数据后检查登录情况?
  • 对不起,我搞错了,你想根据结果返回真/假。你应该使用.map。更新了我的答案。
【解决方案2】:

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

Angular2 canActivate() calling async function

这是我编辑后的代码。

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

如果我返回 Observable(true),则在地图中我得到错误

Type 'Observable&lt;Observable&lt;boolean&gt;&gt;' is not assignable to type 'boolean | Observable&lt;boolean&gt;'.

感谢您的帮助和建议。

【讨论】:

    猜你喜欢
    • 2017-03-13
    • 1970-01-01
    • 1970-01-01
    • 2021-07-18
    • 1970-01-01
    • 2023-02-15
    • 2015-08-05
    • 2021-02-11
    • 2014-03-07
    相关资源
    最近更新 更多