发起效果和行动的最佳实践

Best Practice to initiate Effect and action

所以我花了很多时间让这两种方法起作用,特别是所有 ngrx 操作员。然而,我无法决定哪种方法最适合我正在处理的用例。

所以我有以下情况:

  1. 在页面加载时,我确保用户已登录,并在 auth 功能状态下加载所有用户数据。
  2. 我还想在 settings 功能状态下加载页面加载时的所有设置,但是从 api 加载设置需要具有当前用户 ID,我从上一个步骤。

我的店铺模型如下:

所以我为完成这项工作而实施的两种方法是:

第一种方法

  1. 我在这里加载用户数据,
  2. 每当我收到它的效果时,
    1. 我调度加载设置的 AllSettingsRequested 操作。
@Effect({dispatch: false})
loadUser$ = this.actions$
.pipe(
    ofType<UserRequested>(AuthActionTypes.UserRequested),
    withLatestFrom(this.store.pipe(select(isUserLoaded))),
    filter(([action, _isUserLoaded]) => !_isUserLoaded),
    mergeMap(([action, _isUserLoaded]) => this.auth.getUserByToken()),
    tap(_user => {
        if (_user) {
            this.store.dispatch(new UserLoaded({ user: _user }));
            this.store.dispatch(new AllSettingsRequested()); /* Dispatch the Load Settings Action */
        } else {
            this.store.dispatch(new Logout());
        }
    }),
    catchError(err => {
        console.log(err);
        return of([]);
    })
);

然后在设置效果中我可以简单地添加以下内容:

@Injectable()
export class SettingsEffects {
    loadSettings = createEffect(() => this.actions$.pipe(
        ofType(SettingsActionTypes.AllSettingsRequested),
        withLatestFrom(this.store.pipe(select(currentUser))),
        mergeMap( ([action, user]) => 
                this.settingsService.getSettings( user.id )
            ),
        map(s => {
            return new AllSettingsLoaded({settings: s.model});
        })
    ))
}

方法工作正常,但是从 UserLoaded 效果调度 SettingsRequest 操作感觉不对。

第二种方法

第二种方法是在页面加载时启动 SettingsRequested 操作,让效果等到用户数据加载完毕,然后调用设置 api 并加载设置。

@Injectable()
export class SettingsEffects implements OnInitEffects  {

    loadSettings = createEffect(() => this.actions$.pipe(
        ofType(SettingsActionTypes.AllSettingsRequested),
        mergeMap(action => {
            console.log("im here");
            return combineLatest(
              of(action),
              this.store.pipe(select(currentUser))
            )
             }
          ),
        skipWhile(([action, currentUser]) => {
            console.log('Checking Current User.. ' + currentUser);
            return (!currentUser); 
        }),
        mergeMap( ([action, user]) => 
                this.settingsService.getSettings( user.id )
            ),
        map( (s) => {
            return new AllSettingsLoaded({settings: s.model});
        })
    ));

    /* Dispatch the action on page load */
    ngrxOnInitEffects(): Action {
        return { type: SettingsActionTypes.AllSettingsRequested };
    }

如您所见,这里的效果变得更加复杂,但是,我不需要像第一种方法那样从用户加载效果中分派 SettingsRequest 操作。

我希望我能够阐明问题和两种方法。我的问题是,就 ngrx 最佳实践而言,哪种方法更有意义?

我会选择第三种方法。

我不会从方法一中调度 UserLoadedAllSettingsRequested,而是直接调度 UserLoaded。设置效果可以监听这个动作并获取设置。通过这样做,您也不必从商店中读取用户 ID,因为它存在于 UserLoaded 操作中。