如果ngrx数据不可用,请重试解析程序



我目前有一个详细信息页面的解析器,在转到页面之前,该解析器会检查商店的一部分是否可用

每次有路由器操作(目前我正在尝试所有操作(

ROUTER_REQUEST, ROUTER_NAVIGATED, ROUTER_NAVIGATION

检查存储是否已加载,如果未加载,则会消耗相应的端点并用数据填充存储

然而,当我使用详细信息页面的链接(而不是主页(进入应用程序时,商店会在解析程序之后加载,页面就会挂起。

所以我想尝试两者中的任何一种;重试解析程序函数几次,或者看看是否可以在解析程序之前加载数据。

如果没有存储效果,则加载数据:

loadData$ = createEffect(() => this.actions$.pipe(
ofType<RouterNavigationAction>(ROUTER_REQUEST, ROUTER_NAVIGATED, ROUTER_NAVIGATION),
withLatestFrom(this.store.pipe(select(isLoaded))),
filter(([action, loaded]) => {
return !loaded;
}),
switchMap(() => {
return forkJoin([this.gamesService.getGames(), this.moviesService.getMovies(),
this.musicService.getMusic(40), this.comicsService.getComics(40)])
.pipe(
map((data) => {
const [games, movies, music, comics] = data;
return AppActions.loadDataComplete({ games, movies, music, comics });
})
);
})
));

这是一个函数,也是路由器相关的,早在上面的那个函数之前就执行了。

setPageLoading$ = createEffect(() => this.actions$.pipe(
ofType<RouterNavigationAction>(ROUTER_REQUEST, ROUTER_NAVIGATED),
switchMap((action: Action) => {
// Returns true if request is ROUTER_REQUEST false if ROUTER_NAVIGATED
const loading = action.type.indexOf('request') !== -1;
return of(loading);
}),
map((loading) => {
return AppActions.setPageLoading({ pageLoading: loading });
}),
), { dispatch: true });

解析器:

export class ComicDetailResolver implements Resolve<ComicDetail> {
constructor(private store: Store<State>) {
}
resolve(): Observable<ComicDetail> {
return this.store.pipe(select(getRouteID))
.pipe(
map((routeId: string) => this.store.dispatch(AppActions.getComicDetail({ routeId }))),
switchMap(() => this.store.pipe(select(getItem))),
filter((comic: ComicDetail) => {
console.log(comic, !!comic);
return !!comic;
}), first());
}

我尝试使用重试,但这根本不起作用:

resolve(): any {
this.store.pipe(select(getRouteID))
.pipe(
map((routeId: string) => this.store.dispatch(AppActions.getComicDetail({ routeId }))),
switchMap(() => this.store.pipe(select(getItem))),
map((comic: ComicDetail) => {
let val = null;
if (!comic) {
val = throwError(of(null));
} else {
val = !!comic;
}
console.log(val);
return val;
}), retry(3)).subscribe(data => {
const loaded = !!data ? false : true;
console.log(loaded);
return loaded;
});
}

应@Mikkel Christensen的要求。。。

我有应用程序模块,目前我所有的效果都在路由器效果中:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { EffectsModule } from '@ngrx/effects';
import { StoreModule } from '@ngrx/store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { reducers, metaReducers, CustomSerializer } from '@web/store/reducers';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AppEffects } from '@web/store/effects/main.effects';
import { HttpClientModule } from '@angular/common/http';
import { StoreRouterConnectingModule } from '@ngrx/router-store';
import { RouterEffects } from '@web/store/effects/router.effects';
import { LoadingComponent } from './shared/components/ui/loading/loading/loading.component';
import { HeaderComponent } from './shared/components/header/header.component';
import { LazyLoadImageModule } from 'ng-lazyload-image';
@NgModule({
declarations: [
AppComponent,
LoadingComponent,
HeaderComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
LazyLoadImageModule,
StoreModule.forRoot(reducers, { metaReducers }),
StoreDevtoolsModule.instrument({ maxAge: 25 }),
EffectsModule.forRoot([AppEffects, RouterEffects]),
StoreRouterConnectingModule.forRoot({serializer: CustomSerializer}),
],
providers: [{ provide: Window, useValue: window }],
bootstrap: [AppComponent]
})
export class AppModule { }

我的组件模块延迟加载:

{
path: 'comics',
loadChildren: () => import('./features/comics/comics.module').then(m => m.ComicsModule)
},

希望这就是你的意思,如果这还不够清楚,或者你需要更多信息,请让我知道

问题是(除了我对解析器的理解(;

我检查了详细信息页面的数据,但没有检查主数据是否已加载,即从中提取详细信息的数据。

我试图找到一种方法来重试或让解析器等待,但一旦我让它检查主数据,它就一直在等待(因此我对解析器的理解有所提高(

同样,加载主数据需要一段时间的原因是,它消耗了4个不同的端点,这本身就导致了需要调查的竞争条件。

更新后的代码:

resolve(): Observable<ComicDetail> {
// Added this
return this.store.pipe(select(isLoaded))
.pipe(
filter((loaded: boolean) => {
return !!loaded;
}),
// Added above
switchMap(() => this.store.pipe(select(getRouteID)).pipe(
map((routeId: string) => this.store.dispatch(AppActions.getComicDetail({ routeId }))),
switchMap(() => this.store.pipe(select(getItem))),
)), filter((comic: ComicDetail) => {
console.log(comic, !!comic);
return !!comic;
})
, first());
}

相关内容

最新更新