微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Angular 9 + NGRX:在组件中捕捉效果完成的最佳方法

如何解决Angular 9 + NGRX:在组件中捕捉效果完成的最佳方法

我有一个要创建和帐户的表格:电子邮件,姓名,密码...,我希望应用程序在创建成功时(更确切地说,在效果创建时告诉用户的操作)向用户显示一条消息。已创建。

  • 提交用户创建表单后,我将使用表单的内容向商店调度并采取行动。
  • 派遣该动作时会触发效果
  • 结果是调用服务,该服务在我的后端中调用一个http api,该服务在数据库中创建帐户。
  • 服务完成后,效果将分派新的操作“ UserCreated”

我的问题是:告诉组件正确创建用户的最佳方法是什么?

目前,我已经这样做了:

  • 在完成服务后调用UserCreated动作时,我使用新创建的用户的ID更新商店。

  • 我在ngOnInit中订阅一个选择器,该选择器发送id的值:如果不为空,则显示一条消息。

我觉得这不是最好的方法:我想避免为使用选择器的商店设置id(或布尔值true / false)。

我希望组件订阅该操作:UserCreated,我觉得这更干净(我也可能认为错了)。

我看到了一些有关动作订阅的帖子,但是对我来说不起作用(这些帖子与旧版的angular有关,方法不再存在了。)

提交表格: createaccount.component.ts

this.store.dispatch(new UserServerCreation({ user: _user }));

createaccount.action.ts

export class UserServerCreation implements Action {
readonly type = UserActionTypes.UserServerCreation;
constructor(public payload: { user: User }) { }

createaccount.effects.ts

@Effect()
createuser$ = this.actions$
  .pipe(
    ofType<UserServerCreation>(UserActionTypes.UserServerCreation),mergeMap(({ payload }) => {
      return this.userService.createuser(payload.user).pipe(
        tap(res => {
          this.store.dispatch(new UserCreated({ user: res.payload }));
        }),catchError(error => {
          this.snackBar.open(this.translateService.instant(error.error.errors.message),'Error',{
            duration: 5000,});
          return of([]);

        }),);
    }),);

createaccount.selector.ts

export const selectLastCreatedUserId = createSelector(
  selectUseRSState,useRSState => useRSState.lastCreatedUserId
);
createaccount.component.ts 中的

选择器订阅

ngOnInit() {
  this.store.pipe(select(selectLastCreatedUserId)).subscribe(newId => {
    console.log('ID: ' + newId);
    if (newId) {
      const message = this.translateService.instant('USER.CREATED');
      this.layoutUtilsService.showActionNotification(message,MessageType.Create,5000,true,false);
      this.userForm.reset();
    }
  });
}

更新解决方案:

最终实现了订阅动作频道(这是我首选的方法而不是小吃店)

在我的createaccount.component.ts上,添加以下示例: 变量:

destroy$ = new Subject<boolean>();

在构造函数中:

private actionsListener$: ActionsSubject

然后使用ngOnInit:

this.actionsListener$
  .pipe(ofType(UserActionTypes.LoginondemandCreated))
  .pipe(takeuntil(this.destroy$))
  .subscribe((data: any) => {
    // Do your stuff here
    console.log('DATA : ' + JSON.stringify(data)); //Just for testing purpose
  });

最后进入ngOnDestroy:

ngOnDestroy() {
this.destroy$.next(true);
this.destroy$.complete();

}

感谢帮助!

解决方法

我知道两种方式:

  1. 使用{ dispatch: false }创建另一个效果,这意味着该效果不会调度任何动作,但可以执行一些逻辑操作,例如打开Snackbar。 (ofType<UserServerCreated (UserActionTypes.UserServerCreated))并仅添加一个tap运算符函数,并与catchError中的操作相同。
  2. 您也可以订阅组件到动作的频道。因此,您可以像效果一样过滤此通道。并执行与以前相同的逻辑,或保存此逻辑并在组件中发送消息。 Get error response from ngrx@effects to component
,

尝试

stateSubscription: any;     
 this.stateSubscription = this.store.dispatch(new UserServerCreation({ user: _user }));

  this.stateSubscription = this.store.pipe(select(fromAppLanguage.selectPageState)).subscribe((data) => {
        if (data && data != undefined) {
          if (data['code'] == 200) {

           console.log('---success')
            this.userForm.reset();
          } else {
           console.log('---err')
            this.toastr.error(data['message']);
            this.stateSubscription.unsubscribe();

          }
        }
      });

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。