ToD*_*oDo 2 typescript angular
我想要一种有效的方法来存储(和更新)前端中的当前用户详细信息,而不是在加载新组件时向后端发出新的HTTP GET请求.
我添加了一个UserService类,它在调用类中的方法时设置/更新currentUser对象.
import { Http, Response } from '@angular/http';
import { Injectable } from '@angular/core';
@Injectable()
export class UserService {
public currentUser: any;
constructor(private http: Http) { }
updateCurrentUser() {
this.http.get('api/login/currentUser').subscribe(data => {
this.currentUser = data;
});
}
}
Run Code Online (Sandbox Code Playgroud)
我发现这种方法会导致竞争条件问题.例如,如果currentUser.username在概要文件组件中请求但服务类尚未完成请求,则会发生错误.
我也尝试检查是否currentUser未定义然后调用updateCurrentUser()但它似乎不起作用.
if(this.userService.currentUser === undefined){
this.userService.updateCurrentUser();
}
Run Code Online (Sandbox Code Playgroud)
使用的HTML更新:
我使用数据绑定来显示用户名(直接从UserService类调用它).例如
<span class="username-block">{{userService.currentUser.username}}</span>
Run Code Online (Sandbox Code Playgroud)
我也尝试将currentUser对象分配给我试图显示用户名的组件中的变量,但它具有相同的结果.
我将不胜感激任何帮助/反馈.
您可以在html中尝试Elvis /存在运算符(我认为这是正确的名称).currentUser之后的问号表示如果currentUser未定义,请不要试图评估用户名.
假设您的异步代码最终会填充它,页面应该显示它.
<span class="username-block">{{userService.currentUser?.username}}</span>
Run Code Online (Sandbox Code Playgroud)
编辑
我刚刚注意到你正在输出userService .currentUser.username.您可能希望将服务中的observable返回到组件,以便数据具有反应性.就像是,
updateCurrentUser() {
return this.http.get('api/login/currentUser')
.catch(error => this.handleError(error, 'currentUser'));
}
Run Code Online (Sandbox Code Playgroud)
然后在组件中,
private currentUser;
ngOnInit() {
this.userService.updateCurrentUser()
.take(1)
.subscribe(data => { this.currentUser = data });
}
Run Code Online (Sandbox Code Playgroud)
并且html现在引用本地组件副本,最初未定义但最终由订阅填充.注意,take(1)是关闭订阅并避免内存泄漏.
<span class="username-block">{{currentUser?.username}}</span>
Run Code Online (Sandbox Code Playgroud)
编辑#2
道歉,你的问题是关于避免多个HTTP调用.
在这种情况下,服务代码应该是
export class UserService {
private currentUser: any; // private because only want to access through getCurrentUser()
constructor(private http: Http) { }
getCurrentUser() {
return this.currentUser
? Observable.of(this.currentUser) // wrap cached value for consistent return value
: this.http.get('api/login/currentUser')
.do(data => { this.currentUser = data }) // cache it for next call
.catch(error => this.handleError(error, 'currentUser'));
}
Run Code Online (Sandbox Code Playgroud)
你在使用路由吗?如果是这样,您可以在第一条路线上设置需要用户数据的路线解析器.然后,解析器始终等待显示视图,直到检索到解析器数据.
例如,这是我的一个路线解析器.请注意,它调用服务来检索数据.
import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { IMovie } from './movie';
import { MovieService } from './movie.service';
@Injectable()
export class MovieResolver implements Resolve<IMovie> {
constructor(private movieService: MovieService) { }
resolve(route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<IMovie> {
const id = route.paramMap.get('id');
return this.movieService.getMovie(+id);
}
}
Run Code Online (Sandbox Code Playgroud)
然后将解析器添加到适当的路径,如下所示:
{
path: ':id',
resolve: { movie: MovieResolver },
component: MovieDetailComponent
},
Run Code Online (Sandbox Code Playgroud)
在检索数据之前,不会显示该路线.
| 归档时间: |
|
| 查看次数: |
8801 次 |
| 最近记录: |