Angular NgRx - это плохая практика - использовать store.dispatch в качестве эффекта? - PullRequest
0 голосов
/ 21 октября 2019

Этот вопрос является продолжением этого продолжающегося поста , но я чувствую, что он более узок по объему, и я могу получить ответ самостоятельно на связанный пост.

Справочная информация

В связанном посте я пытаюсь опросить службу для получения данных (где моя проблема заключается в том, чтобы включить или выключить опрос). В моем приложении реального мира вызов на самом деле немного сложнее. Что я хочу сделать, так это вернуть некоторые необязательные http POSTs, and then a GET, always after my POSTS` (поэтому я знаю, что сервер обработал данные POST и будет включен в мои следующие результаты GET.

IF , Я делаю POST, я также хочу отправить действие, чтобы я мог обновить свое состояние, указывая, что произошел POST.

Я преобразовал некоторые из наблюдаемых в обещания, так как я просто нахожу async /ждут, чтобы их было легче понять, чем множество наблюдаемых переключений / отображений и т. д. - я знаю, что это, вероятно, не очень чисто, но, возможно, однажды мои знания оператора rx/js улучшатся (я могу только надеяться). Возможно, кто-то может показать мою лучшую альтернативу(но это не главный вопрос)

Актуальный вопрос

У меня есть следующий код код эффекта , который НЕ отправляетне собственные действия (это будет сделано в this.syncData) ....

    public startPolling$ = createEffect(() => this.actions$.pipe(
        ofType(myActions.startPolling),    
        tap(_ => this.logger.info('effect start polling')),
        tap(() => this.isPollingActive = true),
        switchMap(_ => this.syncData())
      ), { dispatch: false });

И тогда вспомогательный метод ...

    private syncData(): Observable<Action> {        
        const result$: Observable<Action> = Observable.create(async subscriber => {
          try {             
            const pendingEdits = await this.store$.select(fromData.getPendingEditedData).pipe(take(1)).toPromise()
            const pendingNewData = await this.store$.select(fromData.getNewData).pipe(take(1)).toPromise();

            // First post any local updates. These both block, so once they finish we can get the server data knowing any posted
            // data will be included
            if (pendingEdits.length > 0) {
              await this.dataService.postPendinEdits(pendingEdits).toPromise();
              this.store$.dispatch(myActions.editSuccess());
            }

            if (pendingNewData.length > 0) {
              await this.dataService.postPendingNewData(pendingNewData).toPromise();
              this.store$.dispatch(myActions.addNewDataSuccess());
            }

            const dataResult$ = this.dataService.getAllData().pipe(          
              tap(data => {
                this.previousResultsTimeUtc = data.previousResultsTimeUtc;
                if (data.currentDay) {
                  this.store$.dispatch(myActions.getCurrentDaySuccess(data.currentDay));
                  this.store$.dispatch(myActions.getDataSuccess(data));               
                } else {              
                  this.store$.dispatch((myActions.getDataSuccess(data));               
                }
              }),          
              catchError(err => of(myActions.getDataFail(err)))
            );
            const subs2 = dataResult$.subscribe(ss => {
              subs2.unsubscribe();
              subscriber.next(ss);
            });        
          } catch (error) {
            subscriber.error(error);
          }      
        })

        return result$;
      }  

Итак, мы можем видетьв вспомогательном методе я получаю биты состояния магазина, а также dДействия ispatch . Кроме того, в моем приложении есть еще один эффект continuePolling, в котором я также хочу вызвать тот же код в syncData().

Основной вопрос: плохая идея отправлять эти действияиспользование this.store$.dispatch вместо простого возврата нескольких действий из эффекта?

Вызывает ли использование this.store$.dispatch больше выбора для "срабатывания" (следовательно, больше обновления пользовательского интерфейса), где, если я вернул ихИсходя из этого, сначала будут обработаны все действия в редукторах до того, как обновления пользовательского интерфейса произойдут через selects?

Заранее спасибо за любую информацию здесь

1 Ответ

1 голос
/ 21 октября 2019

Лично я бы не ожидал, что syncData будет отправлять действия. Я бы предпочел, чтобы он возвращал действие и позволял ngrx/effects обрабатывать диспетчеризацию действий.

Производительность при этом должна быть одинаковой.

...