如何使用Service存储Angular2的全局变量

时间:2016-12-22 03:15:00

标签: angular angular2-routing angular2-services

我使用AuthService连接到我的auth服务器并存储auth状态,这是必要的代码:

auth.service.ts

@Injectable()
export class AuthService {

  state = {
    isLoggedIn: false,
    redirectUrl: ''
  };


  private authUrl = 'http://localhost:3000/admin/auth'; 

  constructor(private http:Http) {

    this.state.isLoggedIn = false;
    this.state.redirectUrl = '';
  }

  auth(name:string, password:string):Observable<Auth> {

    let headers = new Headers({'Content-Type': 'application/json'});
    let options = new RequestOptions({headers: headers});

    return this.http.post(this.authUrl, {name: name, pw: password}, options)
      .map(this.extractData, this.state)
      .catch(this.handleError);
  }

  extractData(res:Response) { // <-- this.state become undefined

    let body = res.json();

    this.state.isLoggedIn = (body.res == 0); // <-- Cannot read property 'isLoggedIn' of undefined

    return body || {};
  }
}

AUTH-guard.service.ts

@Injectable()
export class AuthGuard implements CanActivate {

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

  canActivate(route:ActivatedRouteSnapshot, stateSnapshot:RouterStateSnapshot):boolean {

    // this.authService.state.isLoggedIn: false
    // this.authService.state.redirectUrl: ''

    let url:string = stateSnapshot.url;

    return this.checkLogin(url);
  }

  checkLogin(url:string):boolean {

    // this.authService.state.isLoggedIn: false

    if (this.authService.state.isLoggedIn) {
      return true;
    }

    // Store the attempted URL for redirecting
    this.authService.state.redirectUrl = url;

    // this.authService.state.redirectUrl: '/admin'

    // Navigate to the login page with extras
    this.router.navigate(['/admin/auth']);
    return false;
  }
}

当我尝试使用名称和密码登录时, auth.service.ts 会说:Cannot read property 'isLoggedIn' of undefined

我不知道为什么以及何时state未定义。

3 个答案:

答案 0 :(得分:1)

看起来你的问题来自这行代码

return this.http.post(this.authUrl, {name: name, pw: password}, options)
  .map(this.extractData, this.state) //<-- right here
  .catch(this.handleError);

地图状态的RXJS文档:

  

map(项目:function(value:T,index:number):R,thisArg:any):Observable   将给定的项目函数应用于源Observable发出的每个值,并将结果值作为Observable发出。

具体看一下map中第二个参数的定义。这指定了&#34;这个&#34;指针。

由于您已将其设置为this.state,并且状态没有名为state的属性,因此您将获得未定义。

您可以传递一个不会尝试并重新绑定此指针的lambda

return this.http.post(this.authUrl, {name: name, pw: password}, options)
  .map((res) => this.extractData(res)) <-- lambda instead
  .catch(this.handleError);

或者你可以只显式传递正确的this指针作为第二个参数

return this.http.post(this.authUrl, {name: name, pw: password}, options)
  .map(this.extractData, this)
  .catch(this.handleError);

答案 1 :(得分:1)

调用 extractData 时,此上下文已更改。使用fat arrow来避免这种情况。

     return this.http.post(this.authUrl, {name: name, pw: password}, options)
      .map((res) => this.extractData(res))
      .catch(this.handleError);

答案 2 :(得分:0)

this.extractData.bind(this);

*不适用于=&gt;功能