ngrx商店随着时间的推移更新

时间:2018-06-04 13:55:48

标签: angular ngrx ngrx-store ngrx-effects

我需要能够将进度更新从我的服务传递到一个愚蠢的组件进行显示。我觉得这应该很简单,只有一些我丢失的愚蠢小事。

详细说明:

  • 我的哑组件中的按钮单击事件触发调度操作以通过效果告诉服务开始下载。
  • 服务通过更新状态进行响应,以便将downloadInProgress标志设置为true并将新状态传递给哑​​UI组件(通过Reducer)
  • 哑UI组件显示正在下载的消息。

那种“封闭”状态循环工作正常。我无法弄清楚的问题是如何从运行下载的服务向dumb ui组件发送定期更新,以便它可以说,例如, x of y下载完成。当服务收到Action以开始下载时,会启动一系列异步下载,每次下载可能需要5-10秒才能完成,所有这些都需要20-30秒才能完成。

如何在每个异步过程完成时发送更新,以告知用户其中一个下载已完成?

这是我的效果:

@Effect()
  startDownload$: Observable<Action> = this.actions$
    .ofType(AppActions.START_DOWNLOAD)
    .switchMap(() => this.appSvc.startDownload())
    .map((appState: IMMAppState) => {
      return new AppActions.StartDownloadSuccessAction(appState);
    });

this.appSvc.startDownload是启动下载过程的电话:

startDownload(): Observable<IMMAppState> {
    //kick off async processes here
    const rv: IMMAppState = this.cloneCurrent(this.currentState) as IMMAppState;
    rv.downloadInProgress = true;

    return Observable.of(rv);
  }

cloneCurrent会对当前状态进行深层复制以保持不变性。

这是我的减速机:

export function MMAppReducer(state: IMMAppState, action: Actions.MMAppActions): any {
  switch (action.type) {
    case Actions.START_DOWNLOAD_SUCCESS:
      return (action as IPayloadAction).payload;
    default:
      return state;
  }
}

这是我的“智能”组件中的调度(哑UI组件的父级):

startDownload(evt: MouseEvent): void {
    this.store.dispatch(new StartDownloadAction());
  }

以下是我的智能组件中的订阅(从ngOnInit调用):

subscribeToAppStore(): void {
    this.appSub = this.store.subscribe((state: IMMState) => {
      if (!state.appState) {
        return;
      }
      //for debugging:
      console.log('downloading: ' + state.appState.downloadInProgress);
    });
  }

我觉得我应该订阅某些东西来接收更新,但我不知道是什么,以及如何将其归结为我的ui组件。

环境:

  • Angular 5.2.7
  • ngrx:5.2.0

谢谢,

TTE

更新

像往常一样,问这个问题给了我一个尝试的想法。这似乎有效,但我不确定这是否是正确的方法:

  startDownload(): Observable<IMMAppState> {
    // kick off async processes here
    const rv: IMMAppState = this.cloneCurrent(this.currentState) as IMMAppState;
    rv.downloadInProgress = true;
    const obs: Observable<IMMAppState> = Observable.create((observer: Observer<IMMAppState>) => {
      setInterval(() => {
        rv.downloadsComplete = this.downloadsComplete;
        observer.next(rv);
      }, 1000);
    });
    return obs;
  }

我在这里使用setInterval只是为了方便全面搞清楚。如果这是正确的方法,我将切换到Observables或Promises以从异步进程获取更新。

所以...这是一个好方法吗?

0 个答案:

没有答案