【问题标题】:How can I subscribe and unsubscribe from individual firestore queries?如何订阅和取消订阅单个 Firestore 查询?
【发布时间】:2020-02-20 01:55:40
【问题描述】:

我正在尝试通过使用两个操作来修改让我开始和停止多个 Firestore 查询的效果。目前,该效果允许我通过侦听效果中的两个单独操作来启动和停止单个 Firestore 查询。当有停止动作时,我只是使用 switchMap 切换到一个空的可观察对象。这工作得很好。

@Effect()
startStopQuery$ = this.actions$.pipe(
  ofType(
    ActionTypes.START,
    ActionTypes.STOP
  ),
  switchMap(action => {
    if (action.type === ActionTypes.STOP) {
      return of([]);
    } else {
      return this.afs.collection('collection', ref => {
        return ref.where('field', '==', 'x');
      }).stateChanges();
    }
  }),
  mergeMap(actions => actions),
  map(action => {
    return {
      type: `[Collection] ${action.type}`,
      payload: { id: action.payload.doc.id, ...action.payload.doc.data() }
    };
  })
);

我真正想做的是进行多个查询,我可以使用这两个相同的操作来启动和停止,但这取决于操作负载。当我每次执行新查询时都修改它时,最后一个停止工作。我认为这是因为 switchMap 运算符从我最后一个可观察的查询中切换。这是我想出的最好的:

@Effect()
startStopQueryById$ = this.actions$.pipe(
  ofType(
    ActionTypes.START_BY_ID,
    ActionTypes.STOP_BY_ID
  ),
  switchMap(action => {
    if (action.type === ActionTypes.STOP_BY_ID) {
      return of([]);
    } else {
      return this.afs.collection('collection', ref => {
        return ref.where('field', '==', action.id);
      }).stateChanges();
    }
  }),
  mergeMap(actions => actions),
  map(action => {
    return {
      type: `[Collection] ${action.type}`,
      payload: { id: action.payload.doc.id, ...action.payload.doc.data() }
    };
  })
);

正如我所说,我认为问题在于 switchMap 运算符。但这也是我首先要使“停止”工作的原因。我似乎无法想出另一种解决方案,因为我还不太熟悉这种风格。

任何帮助将不胜感激!

【问题讨论】:

    标签: ngrx


    【解决方案1】:

    我想出了一个解决方案。我制作了一个将 ID 映射到 firestore statechanges observables 的对象。在开始操作中,我创建了侦听器并将其添加到对象中。我确保它通过管道takeUntil 和相应的停止操作自动取消订阅。它返回对象中所有可观察对象的merge,我像以前一样简单地做。我还有一个由停止动作触发的单独效果,以从对象中删除可观察对象。看起来是这样的:

    queriesById: {[id: string]: Observable<DocumentChangeAction<Element>[]>} = {};
    @Effect()
    startQuery$ = this.actions$.pipe(
      ofType(ActionTypes.START_BY_ID),
      switchMap(action => {
        this.queriesByPlay[action.pid] = this.afs.collection<Element>('requests', ref => {
          return ref.where('field', '==', action.id);
        }).stateChanges().pipe(
          takeUntil(
            this.actions$.pipe(
              ofType(ActionTypes.STOP_BY_ID),
              filter(cancelAction => action.id === cancelAction.id),
            )
          )
        );
        return merge(
          Object.values(this.queriesByPlay)
        );
      }),
      mergeMap(actions => actions),
      mergeMap(actions => actions),
      map(action => {
        return {
          type: `[Collection] ${action.type}`,
          payload: { id: action.payload.doc.id, ...action.payload.doc.data() }
        };
      })
    );
    
    Effect({dispatch: false})
    stopQuery$ = this.actions$.pipe(
      ofType(ActionTypes.STOP_BY_ID),
      map(action => delete this.queriesByPlay[action.id]),
    );
    

    这似乎有效,除了令人费解难以理解之外没有任何问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-30
      • 2022-01-19
      • 2012-03-14
      • 1970-01-01
      • 2015-08-24
      相关资源
      最近更新 更多