2017-03-06 66 views
3

我正在开发个人Angular项目。仍在努力学习和AngularJS移动到角:)Angular 2中的方法不确定或不可调用

这是我的代码:

import { Injectable } from '@angular/core'; 
import { CanActivate, Router } from '@angular/router'; 

import { LoginService } from './login.service'; 

@Injectable() 
export class LoggedInGuard implements CanActivate { 

    constructor(
     private _router: Router, 
     private _loginService: LoginService 
    ) { 
    } 

    isLoggedIn() { 
      let token = localStorage.getItem('token'); 
      if (token) { 
       this._loginService.isLoggedIn(token) 
        .subscribe(v => { 
         return v.status == 'ok'; 
        }); 
      } else { 
       return false; 
      } 
     }; 

    canActivate() { 
     console.log(this.isLoggedIn()); 

     if (this.isLoggedIn()) { 
      return true; 
     } else { 
      this._router.navigate(['/login']); 
      return false; 
     }; 
    } 

} 

但我的问题是:

  1. 如果我继续this.console.log(this.isLoggedIn());则“不确定”打印出来。
  2. 如果我删除它,然后我对VS代码[ts] Cannot find name 'isLoggedIn'. Did you mean the instance member 'this.isLoggedIn'?下面的消息,并在控制台上Uncaught (in promise): ReferenceError: isLoggedIn is not defined
  3. 方法isLoggedIn()同样没有从那里我把它的其他文件有问题时使用。
+0

打印undefined时是否登录?当您注销时,您可以尝试执行代码吗?我认为你正在调用所有东西,但'isLoggedIn'方法在所有情况下都不返回值。 –

回答

2

你所得到的方法未定义的原因:

isLoggedIn() { 
    let token = localStorage.getItem('token'); 
    if (token) { 
     this._loginService.isLoggedIn(token) 
       .subscribe(v => { 
        return v.status == 'ok'; 
     }); 
    } else { 
      return false; 
     } 
}; 

是因为认购this._loginService.isLoggedIn(token)是异步的,不会立即返回。因此方法isLoggedIn()在有响应之前完成执行并返回。

你可以做些什么,而我所做的是让你的_loginService维护一个局部变量,其他组件可以读取和使用,或者一个函数可以同步检查令牌以确保它有效。如果存在令牌,则用户已经登录,并且您可以从中执行的操作是检查令牌以确保它未过期。这可以通过几种不同的方式完成。如果您使用angular2-jwt库来帮助处理您的JWT令牌,你可以在你的_loginService的方法,看起来是这样的:

authenticated() { 
    // Check if there's an unexpired JWT 
    return tokenNotExpired(); 
} 

如果你不使用angular-jwt库,以帮助管理JWT令牌,你可以做这样的事情:

isTokenValid(){ 
    let token = localStorage.getItem('token'); 
    let decodedToken = window.atob(token.split('.')[1]); 

    if((decodedToken.exp * 1000) < Date.now()){ 
     return false; 
    } 
    return true; 
} 

希望有所帮助。

+0

感谢您的回答。由于我不使用'angular2-jwt',我想测试'isTokenValid()'方法。但是,我不确定在“已解码”和“已解码令牌”行之间有什么内容。这些是相同的,只是一个错字,或者你从第一个得到的decodeToken? – Tasos

+0

对不起,这是一个错字。 –

+0

我发现我需要将标记分割为“。”并采取二审。但之后,一切都很好。将您的答案标记为最佳,但请在上次更新时对其进行编辑。万分感谢 – Tasos

1

这可能不符合作为一个答案,但我没有足够的信誉分发表评论 - 让每个人,原谅我:)

我觉得,因为它是一个你无法返回从订阅像这样的价值异步调用..

相反,应退回您的isLoggedIn()方法,如下所示:

isLoggedIn() { 
      let token = localStorage.getItem('token'); 
      if (token) { 
       return this._loginService.isLoggedIn(token) 
        .subscribe(v => { 
         return v.status == 'ok'; 
        }); 
      } else { 
       return false; 
      } 
     }; 

注意的变化是在这里:return this._loginService.isLoggedIn(token)...希望这有助于。

编辑: 忽略我的回答以上......这仍然不能工作:(对不起... 发生了什么事是,你在呼唤isLoggedIn(),它执行异步调用(即通话将继续执行在这就是为什么你会得到一个'undefined',我要做的就是遵循上面的Tyler的建议,并且有一个局部变量,在这个变量中存储返回值并在以后使用,或者你可以传入一个回调函数到isLoggedIn()方法 - 一旦异步调用完成,将调用此回调。如下所示:

import { Injectable } from '@angular/core'; 
import { CanActivate, Router } from '@angular/router'; 

import { LoginService } from './login.service'; 

@Injectable() 
export class LoggedInGuard implements CanActivate { 

    constructor(
     private _router: Router, 
     private _loginService: LoginService 
    ) { 
    } 

    isLoggedIn(callback: (v) => void) { 
      let token = localStorage.getItem('token'); 
      if (token) { 
       this._loginService.isLoggedIn(token) 
        .subscribe(v => { 
         callback(v) 
        }); 
      } 
     }; 

    canActivate() { 
     this.isLoggedIn((v) => { // this here is your callback function which will get invoked once async call is done 
      if(v.status == 'ok' { 
       // do something... 
       return true; 
      } else { 
       // do something 
       this._router.navigate(['/login']); 
      } 
     }); 
    } 

} 
相关问题