使用angular 6应用程序。在那里我必须从API中获取和显示每个页面的用户列表。我已经写了一个完美工作的函数:
listUsers() {
let result = this.http.get('xyz.com/api/users');
result.toPromise()
.then(res => {
this.userList = res.json();
})
.catch(err => {
this.msgService.add({severity: 'error', summary: 'Internal Server Error',
detail: 'There is an Server Error occurred. Please try again later.'});
} );
}我的问题是,我想在超过10个组件/页面中获取用户。我不想在这10个组件中重复上面的函数listUsers()。我希望在一次集中服务中获取所有用户,并从每个组件访问它。
我该怎么做呢?
很抱歉,我没有恰当地表达这个问题。此外,我也找不到任何类似的帖子。如果这个帖子之前已经有人回复了,请告诉我。我将删除这篇重复的帖子。
发布于 2020-03-05 20:20:16
这通常与您的体系结构相关。
如果这几乎是唯一让你恼火的情况,我建议你使用shareReplay,这样你就可以将观察到的结果分享给所有的消费者。
示例:
@Injectable()
export class SomeService {
// ...
public users$: Observable<User[]> = this.http.get('xyz.com/api/users').pipe(
catchError(err => {
this.msgService.add({
severity: 'error',
summary: 'Internal Server Error',
detail: 'There is an Server Error occurred. Please try again later.',
});
throw err;
}),
shareReplay({
bufferSize: 1,
// usually `refCount` should be true so that when all the subscribers
// are not listening anymore, it'll close the observable but here let
// imagine that all your components are not listening to that and then
// later on you come back to it, it will return the previously fetched
// data without fetching it again. If **in that special case** you'd
// prefer to make another request turn that to true
refCount: false,
})
);
// ...
}这样,如果您没有方法,相同的引用将被共享和使用。多亏了shareReplay,你不会再提出另一个请求,除非每个人都取消订阅,然后再有人订阅它。但只要有1个订阅者,之后有多少订阅者加入并不重要,结果将被分享。
你也可以考虑看看这个库:https://github.com/ngneat/cashew,它会简化你的生活,给你更多的控制。
另一种选择是开始研究ngrx,因为它适合根据您在路由上的位置获取数据一次(获取一次),然后将其放入本地“存储”中,所有组件都访问该存储。但这将需要您学习redux/ngrx,并且不会很简单。如果你的应用一直在增长,我会建议你去检查它,因为它真的很有用,但这取决于你的决定,你可以选择你最舒服的。
发布于 2020-03-05 20:47:50
您可以使用ngxs/store进行状态级管理。创建一个User-state.ts类,它需要以下方法
您可以使用选择器标记从存储中获取用户列表,所有组件都可以访问该列表。
@Selector()
static userList(state: UserStateModel) {
return state.UserList;
}
const initialState = {
UserList = []
};
// **make data base call to fetch User list**
@Action(UserActions.GetUserList)
getUserList(
{ patchState, dispatch }: StateContext<UserStateModel>,
{ payload }: UserActions.GetUserList
) {
// call the service to backend call.
return this.UserListService
.getPayments(payload)
.pipe(
tap((apiResp: IApiResponse) => dispatch(new UserActions.GetUserListSuccess(apiResp))),
catchError(error => {
return dispatch(new UserActions.UserListFail(error));
})
);
}
// Using **patchState** you can refresh value of UserList in store
@Action(UserActions.GetUserListSuccess)
GetUserListSuccess(
{ patchState }: StateContext<UserStateModel>,
{ payload }: UserActions.GetUserListSuccess
) {
if (!isNullOrUndefined(payload)
&& !isNullOrUndefined(payload.result)
&& !isNullOrUndefined(payload.resultdata)) {
return patchState({
UserList: payload.resultdata.UserList
});
}
return **patchState**({ UserList: initialState.UserList});
}//再创建一个文件UserAction.ts,包含以下两个类
export class GetUserList {
static readonly type = '[UserList] Get Payment Details';
}
export class GetUserSuccess {
static readonly type = '[Userlist] Get User List Success';
constructor(public payload?: any) { }
}发布于 2020-03-05 20:10:08
基于服务注入的Ngrx
单击此处(Angular 6 - Why use @ngrx/store rather than service injection)。
希望你得到这个伟大的功能,可以用来解决这个问题。
https://stackoverflow.com/questions/60544958
复制相似问题