redux - NGRX 效果中的多个操作

标签 redux ngrx ngrx-effects

在学习 Angular 和 NGRX 时,遇到了我认为是常见问题的简单示例,但无法理解在 Redux 存储\效果模式中完成控制逻辑的最佳方法。

一般流程:

用户输入信用卡信息,点击支付按钮 > 从组件分派(dispatch)“GetTokenAction” > 向外部第 3 方 API 发出 Http 请求以进行 token 化 > 如果成功,则将该信息提交给 Payment API

这是我最近的尝试:

    @Effect() getToken$ = this.actions$
    .ofType(TokenizerActions.GET_TOKEN)
    .pipe(switchMap((action: TokenizerActions.GetTokenAction) => {
        return this.TokenizerApiService.getToken(action.payload)
            .pipe(
                map(tokenResponse => {
                        console.log(tokenResponse);
                        // service will return 200 with "declined" status. In this case I want to treat it like an Error.
                        if (tokenResponse.results.Error != null) {
                            return new TokenizerActions.GetTokenFailedAction(tokenResponse.results.Error.messages);
                        }
                        // What is best practice here?  Call Payment Service? Dispatch Actions? Where should this mapping logic live?
                        const paymentRequest: PaymentRequest = new PaymentRequest();
                        paymentRequest.token = tokenResponse.results.token;
                        paymentRequest.amount = action.payload.amount;
                        paymentRequest.customerNumber = action.payload.customerNumber;
                        paymentRequest.correlationId = tokenResponse.results.correlation_id;
                        // this does not work, "dispatched an invalid action: undefined" error.
                        mergeMap((payReq: PaymentRequest) => [new paymentActions.MakePaymentAction(paymentRequest),
                        new TokenizerActions.GetTokenSuccessAction(tokenResponse.results.token)]);
                    }),
                catchError(error => of(new TokenizerActions.GetTokenFailedAction(error)))
            );
    }));

constructor(
    private actions$: Actions,
    private TokenizerApiService: TokenizerApiService,
    private paymentApiService: PaymentApiService
) { }

问题/注意事项:

该效果是否适合处理此问题?第一个工作版本具有控制流程和分派(dispatch)多个操作的组件,也可以在服务内处理,不确定哪种是最佳实践。

效果模式中错误通知的首选方法是什么?在线和示例应用程序中有很多简单的示例,但我无法将其转换为稍微复杂的示例(检查响应,然后抛出错误并根据需要停止处理)。目前该应用程序正在执行以下操作:

    <span class="error" *ngFor="let error of tokenErrors$ | async">{{error.description}}</span>
    <span class="error" *ngFor="let error of paymentErrors$ | async">{{error.description}}</span>
    <div class="success" *ngIf="(payment$ | async)?.transactionStatus === 'approved'">Success</div>

this.paymentErrors$ = this.store.select(state => state.payment.paymentErrorMessages);
this.tokenErrors$ = this.store.select(state => state.token.tokenErrorMessages);
this.payment$ = this.store.select(state => state.payment.paymentStatus);

可以再简单点吗?是否应该将错误合并到一个 PayError 数组中?如果订阅的话,组件级别是否有问题,还是全部都在效果级别处理?

最佳答案

首先,不要直接执行箭头函数,而是创建选择器。

其次,使用一个选择器(而不是 3 个不同的选择器)选择该组件所需的 ViewModel (transactionInfo)。您可以组合多个选择器来实现此目的。 例如,可以使用 *ngIf 将结果在模板中推到更高的位置

<ng-container *ngIf="transactionInfo$ | async as transactionInfo">
  <span class="error" *ngFor="let error of tokenErrors">{{error.description}}</span>
    <span class="error" *ngFor="let error of transactionInfo.paymentErrors">{{error.description}}</span>
    <div class="success" *ngIf="transactionInfo.transactionStatus === 'approved'">Success</div>
</ng-container>

关于redux - NGRX 效果中的多个操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52011318/

相关文章:

javascript - 单击自定义按钮组件时热隐藏组件

angular - 是否有类似于 withLatestFrom 但带有参数的 RxJS 运算符?

angular - 使用 Nrwl 的 Nx 中的数据持久化模块,悲观更新的实现与乐观更新有何不同

reactjs - 当使用 redux 和 componentWillMount 时,防止 React 组件渲染两次

reactjs - Redux调用dispatch函数但不改变store

javascript - 将 redux 操作拼接到历史中

ngrx - 如果我收到的内容类型是 JSON-LD + Hydra,我应该使用 ngrx-data 吗?

angular - NGRX 8 将元素添加到存储中的数组

angular - ngrx/effects 方法比 redux-thunk 有什么优势?

angular7 - NGRX 相互嵌套多个功能模块?