我有一个服务UserService
,它具有方法getUsers()
,并且该服务在不同的角度组件之间共享。
该方法调用API并返回数据。我想保留上一个API调用的结果/状态,所以我使用BehaviorSubject
来保留上一个状态,这样,如果不同的组件调用getUsers()
时应该只有一个API调用,否则必须返回保持状态。
这就是我要实现的方式
private _users$: BehaviorSubject<User[]>;
constructor(private http: HttpClient) {
this._users$ = new BehaviorSubject([]);
}
getUsers(): BehaviorSubject<User[]> {
if (!this._getUsersState().length) {
this._loadUsers();
this._users$.subscribe(() => {
return this._users$;
});
} else {
return this._users$;
}
}
_loadUsers() {
let _users$ = this.http.get(`${this._context}/users/`);
_users$.subscribe((users: User[]) => {
this._users$.next(Object.assign([], users));
});
}
_getUsersState(): User[] {
return this._users$.getValue();
}
在组件中
this.userService.getUsers().subscribe((users: any) => {
console.log(users);
});
但是我遇到了以下错误
ERROR TypeError: Cannot read property 'subscribe' of undefined
如果长度为0,我想让用户自动返回。
如何解决此问题?这种方法好吗?
答案 0 :(得分:0)
像这样编辑服务:
private _users$ = new BehaviorSubject<User[]>(null);
public usersChanged = this._users$.asObservable();
constructor(private http: HttpClient) {
}
getUsers(): BehaviorSubject<User[]> {
if (!this._getUsersState().length) {
this._loadUsers();
this._users$.subscribe(() => {
return this._users$;
});
} else {
return this._users$;
}
}
_loadUsers() {
let _users$ = this.http.get(`${this._context}/users/`);
_users$.subscribe((users: User[]) => {
this._users$.next(Object.assign([], users));
});
}
_getUsersState(): User[] {
return this._users$.getValue();
}
像这样编辑组件逻辑:
this.userService.usersChanged
.subscribe((users: any) => {
if(!!users){
console.log(users);
} else {
console.log("No user found!");
}
});
有一个可观察到您的private
behaviorSubject的变量是一个好习惯。因此,您只需订阅它,只要它的状态发生变化,它就会发出。
答案 1 :(得分:0)
getUsers方法应该返回一个可观察的对象,在服务中订阅可观察的对象不是一个好习惯。 如果要维护用户状态,请使用单例服务。这样声明服务中的属性:
public users: Users[] = [];
private getUsers(): Observable<Users[]> {
if (!this.users.length) {
return this.http.get(`${this._context}/users/`);
}
return Observable.of(this.users);
}
在您的组件中
this.userService.getUsers().subscribe((users: User[]) => {
this.userService.users = users; // (or users.slice(0)
console.log(users);
});