Angular 4:无法从CanActivate AccessGuard订阅可观察值

时间:2017-08-25 19:07:20

标签: javascript angular typescript

我遵循了很多教程并尝试了很多组合,但却无法完成这项工作。

我需要在用户登录时让路由可用。如果他不是我需要将他重定向到主页(this._popupService.setCallbackRoute(route.url.join('/')))并显示一个弹出窗口(this._popupService.showPopUp()),让他登录或注册。

我无法从authService获取同步值。这是我的代码:

app.module.ts

imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    RouterModule.forRoot(
        {path: '', component: HomepageComponent},
        {
            path: 'protectedRoute',
            component: SubmitComponent,
            data: {requiresLogin: true},
            canActivate: [AccessGuard]
        }
    ),
    ...
]

auth.service.ts

 @Injectable()
export class AuthService {

    private loggedIn: Subject<boolean> = new Subject<boolean>();

    get isLoggedIn() {
        return this.loggedIn.asObservable();
    }

    login(user: IUser) {
        return this._http.get('assets/api/responseSuccess.json?email=' + user.email + '&password=' + user.password)
            .map((responseLogin => {
                const jsonResponse = responseLogin.json();
                if (jsonResponse.response === 'success') {
                    const userResponse: IUser = jsonResponse.user;
                    this._sessionService.setUserSession(userResponse);
                    this.loggedIn.next(true);
                    return true;
                } else {
                    this._customFlashMessages.show('Got error login, please check your credentials and try again!');
                    return false;
                }
            }));
    }
}

accessGuard.service.ts

import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, CanActivate, Router} from '@angular/router';
import {Observable} from 'rxjs/Observable';
import {AuthService} from './auth.service';
import {PopUpService} from './popup.service';

@Injectable()
export class AccessGuard implements CanActivate {
    loggedIn$: Observable<boolean>;

    constructor(private authService: AuthService, private _popupService: PopUpService, private router: Router) {
        this.loggedIn$ = this.authService.isLoggedIn;
    }

    canActivate(route: ActivatedRouteSnapshot): Observable<boolean> | Promise<boolean> | boolean {
        const requiresLogin = route.data.requiresLogin || false;
        if (requiresLogin) {
            this.authService.isLoggedIn.subscribe( // even tried with .map()
                result => {
                    console.log(result); // Logs a promise object
                    if (!result) {
                        console.log("protected route"); // Never reached
                        // If not logged in shop popup and stay on that page
                        this._popupService.showPopUp();
                        this._popupService.setCallbackRoute(route.url.join('/'));
                        return false;
                    }
                    console.log('logged in'); // Never reached
                    return true;
                });
        }
        return true;
    }
}

我尝试了几件事。如果我直接检查sessionStorage('user')但不使用observable,我的代码可以工作。

感谢任何帮助。

谢谢!

2 个答案:

答案 0 :(得分:0)

你需要返回一个observable。

canActivate(route: ActivatedRouteSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    const requiresLogin = route.data.requiresLogin || false;
    if (requiresLogin) {
        return this.authService.isLoggedIn;
    }
    return Observable.of(false);
}

答案 1 :(得分:0)

这是正确的答案,问题出在subscribe方法的逻辑中。

这里有正确的 accesGuard.service.ts

@Injectable()
export class AccessGuard implements CanActivate {

    constructor(private authService: AuthService, private _popupService: PopUpService, private router: Router) {
    }

    canActivate(route: ActivatedRouteSnapshot): Observable<boolean> | Promise<boolean> | boolean {
        const requiresLogin = route.data.requiresLogin || false;
        if (requiresLogin) {
            this.authService.isLoggedIn.subscribe(
                result => {
                    if (!result) {
                        // If not logged in shop popup and stay on that page
                        this._popupService.showPopUp();
                        this._popupService.setCallbackRoute(route.url.join('/'));
                        this.router.navigate(['/']);
                        return false;
                    }
                    return true;
                });

            return true;
        }else{

        return true;
       }
    }
}