我使用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
未定义。
答案 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;功能