Angular ngrx - 显示正在加载gif

use*_*298 16 ngrx ngrx-effects angular ngrx-store

我有这样的副作用:

@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));
Run Code Online (Sandbox Code Playgroud)

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

我创建了一组独立的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
};
Run Code Online (Sandbox Code Playgroud)

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

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

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

max*_*992 18

我们举一个例子:如果你想获取用户.

我通常为此做的事情:
- 调度一个动作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))
        )
      )
    )
  );
Run Code Online (Sandbox Code Playgroud)

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

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

<div loadingUser>
  Fetching user information
</div>
Run Code Online (Sandbox Code Playgroud)


小智 2

为了实现这一点,你可以使用这个 npm 包https://www.npmjs.com/package/angular2-busy

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

busy: Promise<any>; 
Run Code Online (Sandbox Code Playgroud)

或者

busy: Subscription;
Run Code Online (Sandbox Code Playgroud)

然后像下面一样使用这个变量

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));
Run Code Online (Sandbox Code Playgroud)

如果您想使用 busyActions 类,那么您必须将该类导入到您的组件中,并在组件构造函数中创建一个私有变量,并在必要时调用该类所需的操作。但对我来说,最好使用上面的包,它效果很好。