Angular ngrx - 显示正在加载gif

时间:2017-12-11 14:47:05

标签: angular ngrx ngrx-store ngrx-effects

我有这样的副作用:

@Effect()
FetchAllOrders$ = this.actions$
    .ofType(SalesOrderActions.FETCH_ALL_ORDERS)
    .switchMap((action: Action) => {
        return this.soApiService.getUsersSalesOrders(action.payload);
    })
    .map((salesOrders: ListDto<SalesOrderList>) => this.actions.fetchAllOrdersSuccess(salesOrders));

我想在效果开始时显示加载符号并在结尾隐藏它。

我创建了一组独立的Actions,Reducers和store状态来处理显示加载符号。

export class BusyActions {
static SHOW_SPINNER = "SHOW_SPINNER";
static HIDE_SPINNER = "HIDE_SPINNER";

showSpinner(): Action {
   return { type: BusyActions.SHOW_SPINNER };
}

hideSpinner(): Action {
   return { type: BusyActions.HIDE_SPINNER };
}

export const BusyState: IBusyState = {
   visible: false,
   busy: false
};

我这样做是因为加载状态需要与其他模块,状态等共享。

如何从副作用中调用我的BusyActions?我需要在开始时调用SHOW_SPINNER,最后调用HIDE_SPINNER。

我做得对吗?或者有更好的方法来解决这个问题吗?

2 个答案:

答案 0 :(得分:17)

让我们举一个例子:如果你想取一个用户。

我通常为此做的事:
  - 派遣行动FetchUser
  - 在reducer中,在users上设置一个标记:isUserFetching: true
  - 在效果中捕获该动作
  - 打电话给你想要的东西,例如服务   - 当服务返回他提取的内容时,将其映射到成功操作:FetchUserSuccess
  - 如果出现问题,请将错误映射到错误操作:FetchUserError
  - 在您的用户缩减器中,如果FetchUserSuccess执行您想要的操作+设置isUserFetching: false
  - 在您的用户缩减器中,如果FetchUserError执行您想要的操作+设置isUserFetching: false

@Effect()
fetchUser$: Observable<Action> = this.actions$
  .ofType(FetchUser)
  .pipe(
    switchMap(action =>
      this.usersService.fetchUser(action.payload).pipe(
        map(
          res =>
            new FetchUserSuccess({
              id: action.payload.id,
              data: res,
            })
        ),
        catchError((err: HttpErrorResponse) => 
          of(new FetchUserError(action.payload))
        )
      )
    )
  );

在您的视图中,您可以选择商店的好部分为变量,让我们说isFetchingUser$并执行:

<div *ngIf="isFetchingUser$ | async; else #loadingUser">
  Show the user here
</div>

<div loadingUser>
  Fetching user information
</div>

答案 1 :(得分:2)

要实现此目的,您可以使用此npm包https://www.npmjs.com/package/angular2-busy

在你的情况下添加所有必要的模块以使用包后,你需要声明一个变量

busy: Promise<any>; 

busy: Subscription;

然后使用此变量,如下所示

this.busy = this.actions$
.ofType(SalesOrderActions.FETCH_ALL_ORDERS)
.switchMap((action: Action) => {
    return this.soApiService.getUsersSalesOrders(action.payload);
})
.map((salesOrders: ListDto<SalesOrderList>) => this.actions.fetchAllOrdersSuccess(salesOrders));

如果要使用busyActions类,则必须将此类导入到组件中,并在组件构造函数中创建一个私有变量,并在必要时调用所需的类操作。但对我而言,最好使用上述非常好的包装。