Ngxs-如何链接动作?

Jon*_*ger 2 state angular ngxs

我想做这样的事情来注册。

单击注册按钮时,将执行以下操作:

this.store.dispatch(new Register(user))
    .subscribe(response => {
      localStorage.setItem('token', JSON.stringify(response.token));
      let redirectUrl = this.store.dispatch(new RegisterSuccess(response));

      if (redirectUrl) {
        this.router.navigate([redirectUrl]);
      } else {
        this.router.navigate(['/home']);
      }
    }, error => {
      this.store.dispatch(new RegisterFailed());
    });
Run Code Online (Sandbox Code Playgroud)

州:

  @Action(Register)
  register({ patchState }: StateContext<AuthenticationStateModel>, { payload }: Register) {
    patchState({
      isLoading: true
    });

    return this.authenticationService.register(payload);
  }

  @Action(RegisterFailed)
  registerFailed({ patchState }: StateContext<AuthenticationStateModel>) {
    patchState({
      isLoading: false
    });
  }

  @Action(RegisterSuccess)
  registerSuccess(sc: StateContext<AuthenticationStateModel>, { payload }: RegisterSuccess) {
    sc.patchState({
      user: payload.user,
      token: payload.token,
      isAuthenticated: true,
      isLoading: false,
    });

    return sc.getState().redirectUrl;
  }
Run Code Online (Sandbox Code Playgroud)

1)我希望Register动作从http请求返回Observable。
2)然后订阅它,如果请求成功,则触发RegisterSuccess(我希望它从状态返回一个项目)。如果请求失败,则触发RegisterFailed。

我实际上已经通过将相同的代码放入状态(对c进行了少量修改)来完成此操作,但是我觉得它太乱了,不是正确的方式,因此将其放入组件中,但是我无法使其再次正常工作。

riv*_*nov 5

文档建议您执行以下操作:

对于同步操作:

return ctx.dispatch(new TakeAnimalsOutside());

对于异步操作:

return this.animalService.feed(action.animalsToFeed).pipe( ... mergeMap(() => ctx.dispatch(new TakeAnimalsOutside()))

有趣的dispatch是,您可以 dispatch([new Action1(), new Action2(), ...etc])


kct*_*ang 3

我就是这样做的:

  • 当用户执行操作时,只需使用操作参数(如果有)进行分派,例如new MyAction()。一般来说,不需要订阅这个分派的动作,而且我发现它也让代码看起来很混乱。
  • @Action函数处理内容并可选地分派成功/失败的操作(例如MyActionSuccessMyActionFailed,或一些其他有意义的操作)。如果此操作只能有一个结果,则不必费心调度成功 - 完成此操作就是成功。
  • 为了处理操作的成功(等等)执行,我订阅了用于路由/重定向内容的操作处理程序。组件将根据组件的生命周期订阅/取消订阅这些内容。(例如ngOnInit()ngOnDestroy())。

老实说,我不知道这是正确的还是最好的方法,只是我现在正在这样做。