更新数据后,NgRx 如何更新远程数据?



我在理解NgRx的工作原理时遇到了麻烦。我有一个用户列表,该列表是通过 Firebase 商店的服务加载的,如下所示:

getAllUsers():Observable<object>{
console.log('getAllUsers');
return this.afs.collection('users', (ref:any) => ref.where("role", '!=', 'admin')).valueChanges();
}

然后我在存储用户列表的模块中有一个商店设置,它工作得很好,并在管理员登录到应用程序时加载用户列表一次,因为它在仪表板中调度,仪表板是管理路由器插座的容器。管理员可以单击每个用户并更新其信息,从而从未连接到商店的服务中触发此功能:

async updateUserData(data:any, id:any){
await this.afs.collection('users').doc(id).update(data); 
} 

我期望当用户数据更新时,存储的用户列表在再次下载之前不会更新,但它会相应地更新。 这是怎么回事?我正在记录 getAllUsers 函数,但没有再次调用它。取而代之的是操作:当调用更新用户数据时,将调用 LoadUsersSuccess,但它们在效果中的任何位置都没有连接。我真的很想知道这是怎么发生的,但我在任何地方都找不到答案。这是我的商店设置-

actions.ts:

import { Action } from "@ngrx/store";
export enum AdminActionTypes{
LOAD_USERS = '[ADMIN] Load Users',
LOAD_USERS_SUCCESS = '[ADMIN] Load Users Success',
LOAD_USERS_FAILURE = '[ADMIN] Load Users Failure',
}
export class LoadUsersAction implements Action {
readonly type = AdminActionTypes.LOAD_USERS;
}
export class LoadUsersSuccessAction implements Action {
readonly type = AdminActionTypes.LOAD_USERS_SUCCESS;
constructor(public payload: any){}
}
export class LoadUsersFailureAction implements Action {
readonly type = AdminActionTypes.LOAD_USERS_FAILURE;
constructor(public payload: Error){}
}
export type AdminAction = LoadUsersAction | LoadUsersFailureAction | LoadUsersSuccessAction;

reducer.ts:

import { AdminActionTypes, AdminAction} from './admin.actions';
import { createFeature, createFeatureSelector, createSelector } from '@ngrx/store';
export interface AdminState {
list: any[],
loading: boolean,
error: Error
}
const initialState: AdminState = {
list:[],
loading:false,
error: {name: "", message: ""}
}
export function AdminReducer(
state: AdminState = initialState,
action: AdminAction,
){
switch (action.type){
case AdminActionTypes.LOAD_USERS:
return {...state,  loading: true};
case AdminActionTypes.LOAD_USERS_SUCCESS:
return {...state, list:action.payload, loading:false};
case AdminActionTypes.LOAD_USERS_FAILURE:
return {...state, error:action.payload, loading:false};
default:
return state;
}
}
export const getAdminState = createFeatureSelector<AdminState>('admin');
export const loadUsers = createSelector(getAdminState, (state: AdminState) => state.loading);
export const loadUsersSuccess = createSelector(getAdminState, (state: AdminState) => state.list);
export const loadUsersFailure = createSelector(getAdminState, (state: AdminState) => state.error);

效果.ts:


@Injectable()
export class AdminEffects {
loadUsers$ = createEffect(
() => this.actions$
.pipe(
ofType<LoadUsersAction>(AdminActionTypes.LOAD_USERS), 
mergeMap(
() => this.adminService.getAllUsers()
.pipe(
map(data => new LoadUsersSuccessAction(data)),
catchError(error => of (new LoadUsersFailureAction(error)))
),
),
),
)
constructor(
private actions$: Actions, 
private adminService: AdminService
){}
}

我认为发生这种情况是因为您从getAllUsers返回一个Observable,当 Firebase 集合发生变化时会发出一个值。然后返回的Observable通过mergeMaploadUsers$效应的可观察量在内部链接,当一个新值来自源可观察量(this.adminService.getAllUsers())时,该可观察量映射到LoadUsersSuccessAction操作,然后LoadUsersSuccessAction被调度。

因此,如果您想更改此行为,则需要在第一个值来自 Firebase 集合时立即完成可观察getAllUsers(),如下所示:

getAllUsers(): Observable<object> {
console.log('getAllUsers');
return this.afs
.collection('users', (ref: any) => ref.where('role', '!=', 'admin'))
.valueChanges()
.pipe(take(1));
}

或者您需要从效果中提取逻辑(从 firebase 获取valuesChanges)并在其他地方使用它。

最新更新