Отправка действия на основе данных, полученных из предыдущего действия - PullRequest
1 голос
/ 09 марта 2020

Я борюсь с отправкой действия после завершения предыдущего.

Что я хочу сделать, это отправить действие (скажем, getDetails), а затем использовать данные, поступающие из этого действия, для отправки другого действия (скажем, getUserLists). Затем, когда это последнее действие завершится, я хочу перейти к маршруту.

Я не уверен, как связать эти действия. Это то, что я попробовал прямо на моем компоненте (я слышал, что этот вид логики c должен быть внутри эффекта, поэтому моя цель здесь только показать, что я сделал):

this.store.dispatch(DetailsActions.getDetails({ bt: '00079138' }));
    this.store.select(fromApp.selectDetails)
      .pipe(
        // which operator I have to use here???
        tap((clientId) => this.store.dispatch(ProfileActions.getUsersList({ clientId })),
        first()
      )
      .subscribe(() => this.router.navigate(['tabs/home'], { replaceUrl: true }));

Это так? исправить подход, который я выбрал? Есть несколько рекомендаций?

Заранее спасибо.

ОБНОВЛЕНИЕ Попробовал решение @calimoose, реализовав новое действие, которое выполняет следующие действия :

this.actions$.pipe(
            ofType(ProfileActions.populateApiInfo),
            flatMap((data) => of(DetailsActions.getDetails({ bt: data.bt }))),
            withLatestFrom(this.store.select(fromApp.selectClientId)),
            flatMap(([_, clientId]) => of(ProfileActions.getUsersList({ clientId }))),
            withLatestFrom(this.store.select(fromApp.selectPbList)),
            map(([_, pbList]) => {
                return ProfileActions.populateApiInfoSuccess();
            })
        ));

Но, похоже, он не отправляет действия getDetails и getUsersList. Что-то не так в цепочке операторов?

ОБНОВЛЕНИЕ 2 Пробовал, как предлагал @Friso, но действия getDetails и getUsersList не отправляются

   this.actions$.pipe(
            ofType(ProfileActions.populateApiInfo),
            concatMap((data) =>
                of(DetailsActions.getDetails({ bt: data.bt }))
                    .pipe(
                        withLatestFrom(this.store.select(fromApp.selectClientId)),
                        concatMap(([_, clientId]) =>
                            of(ProfileActions.getUsersList({ clientId }))
                                .pipe(
                                    withLatestFrom(this.store.select(fromApp.selectPbList)),
                                    map(([_, pbList]) => {
                                        return ProfileActions.populateApiInfoSuccess();
                                    })
                                )
                        ),
                    )
            )
        ));

1 Ответ

2 голосов
/ 09 марта 2020

Использование эффекта, который возвращает ваше следующее действие, было бы лучшим вариантом здесь. См. Также: документы

getUsersList$ = createEffect(() => this.actions$.pipe(
    ofType(DetailsActions.getDetails),
    withLatestFrom(*/ insert clientId Selector here */),
    map([_, clientId], => of(ProfileActions.getUsersList({ clientId }))
    )
  );

обязательно прочитайте документы ngrx, если вы не уверены в концепции:

withLatestFrom начинает слушать данные сразу, независимо от поступающего действия, поэтому вы можете использовать оператор выравнивания, чтобы предотвратить это:

.pipe(
  ofType(thePreviousAction),
  concatMap(action => of(action).pipe(
    withLatestFrom(this.store.pipe(select(getYourData)))
  )),
  // do stuff
)

@Effect требует, чтобы вы вернули новое действие. В некоторых случаях вы можете не захотеть этого делать. Вы можете использовать { dispatch: false }, чтобы игнорировать это требование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...