#angular #rxjs #ngrx-store #angular-route-guards
#angular #rxjs #ngrx-store #angular-route-guards
Вопрос:
У меня возникла проблема с тем, что мой CanActivateChild route guard не ожидает возврата данных из 3 вызовов службы на серверную часть, прежде чем определять, может ли он активировать маршрут или нет. Я подключил его к хранилищу ngRx и отправляю 3 отдельных действия, а затем использую forkJoin, чтобы вернуть то, что, как я думал, будет наблюдаемым относительно того, все ли они возвращают данные или нет. Похоже, это не работает должным образом, потому что один из 3 обычно возвращает undefined в компоненте.
Насколько я понимаю, select возвращает наблюдаемое, а filter / take(1) гарантирует, что наблюдаемое завершится после выполнения условия. Кажется, это работает должным образом, поскольку оно попадает в фильтр несколько раз, в конечном итоге получая данные для 2 из них. Я не понимаю, почему он вернет true, если один из элементов не возвращает данных.
Любая помощь относительно того, как заставить это работать должным образом?
getFromStoreOrAPI(): Observable<any> {
return forkJoin(
this.store.select(getFinancialFactors).pipe(filter(financialFactors => financialFactors amp;amp; financialFactors.length > 0), take(1)),
this.store.select(getFinancialData).pipe(filter(financialData => financialData amp;amp; financialData.length > 0),take(1)),
this.store.select(getFranchiseData).pipe(filter(franchiseData => franchiseData amp;amp; franchiseData.length > 0),take(1))
);
}
canActivateChild(route: ActivatedRouteSnapshot): Observable<boolean> | boolean {
let tranId = this.router.getCurrentNavigation().extras.state.tranId;
let modelId = this.outer.getCurrentNavigation().extras.state.modelId;
this.store.dispatch(ScorecardActions.loadFinancialData({tranId: tranId}));
this.store.dispatch(ScorecardActions.loadFranchiseData({tranId: tranId}));
this.store.dispatch(ScorecardActions.loadFinancialFactors({modelId: modelId}));
return this.getFromStoreOrAPI()
.pipe(
switchMap(() => of(true)),
catchError(() => of(false))
);
}
}
Комментарии:
1. я считаю, что если у одного элемента нет данных, он вернет пустое наблюдаемое значение, а не «of (true)» в вашем случае. просто никаких событий не поступает из
getFromStoreOrAPI()
2. также вы уверены, что вам нужна
canActiveChild
, а не простоcanActivate
защита в вашем случае? может решить проблему3. @Andrey да, guard находится на родительском для дочерних маршрутов, поэтому он должен быть CanActivateChild. Кроме того, не должен ли фильтр предотвращать завершение наблюдаемого без данных, поскольку take (1) не будет выполняться и, следовательно, не завершит наблюдаемое?
4. всегда ли loadFinancialData и другие действия по загрузке порождают http-запрос?
5. @Andrey да, 3 отдельных HTTP-вызова выполняются через 3 отдельные службы для контроллера на серверной части (ASP.NET ), которые в конечном итоге попадают в одну и ту же базу данных SQL Server.