使用NGRX时如何避免不必要的API调用

发布于 2025-01-24 15:19:18 字数 1364 浏览 2 评论 0原文

我有一个带有2个菜单项的应用程序;团队,球员。每当我之间切换它们时,即使我在存储中有数据,我也必须不必要的API调用。

以下是效果文件: //auth.effects.ts

loadTeams$ = createEffect(() => {
    return this.actions$.pipe(
      ofType(AuthActions.loadTeams),
      switchMap((action) =>
        this.apiService.teams$.pipe(
          tap(() => console.log('get teams request')),
          map((teams: Team[]) => AuthActions.loadTeamsSuccess({ teams })),
          catchError((error) => {
            console.log('err', error);
            return of(AuthActions.loadFailure({ error }));
          })
        )
      )
    );
  });

以下是我将API呼叫

teams-list.component.ts

export class TeamsListComponent implements OnInit {
  loading$?: Observable<boolean>;
  error$?: Observable<string>;
  teams$?: Observable<Team[]>;
  retrySubject$ = new BehaviorSubject<boolean>(true);

  constructor(private store: Store<State>) {}

  ngOnInit(): void {
    this.store.dispatch(loadTeams());
    this.teams$ = this.store.select(getTeams);
    this.error$ = this.store.select(getError);
    this.loading$ = this.store.select(getLoading);
  }

  fetchRetry() {
    this.retrySubject$.next(false);
  }
}

在ngoninit中进行的组件,导致不必要的API调用。 this.teams $ = this.store.select(getTeams);

如何预防它,以便在初始化应用程序时使API一次调用?

I have an application with 2 menu item; Teams, Players. Whenever I toggle between them, I have to unnecessary api call even though I have the data in store.

Below is the effects file:
//auth.effects.ts

loadTeams$ = createEffect(() => {
    return this.actions$.pipe(
      ofType(AuthActions.loadTeams),
      switchMap((action) =>
        this.apiService.teams$.pipe(
          tap(() => console.log('get teams request')),
          map((teams: Team[]) => AuthActions.loadTeamsSuccess({ teams })),
          catchError((error) => {
            console.log('err', error);
            return of(AuthActions.loadFailure({ error }));
          })
        )
      )
    );
  });

Below is the component from which I make api call

teams-list.component.ts

export class TeamsListComponent implements OnInit {
  loading$?: Observable<boolean>;
  error$?: Observable<string>;
  teams$?: Observable<Team[]>;
  retrySubject$ = new BehaviorSubject<boolean>(true);

  constructor(private store: Store<State>) {}

  ngOnInit(): void {
    this.store.dispatch(loadTeams());
    this.teams$ = this.store.select(getTeams);
    this.error$ = this.store.select(getError);
    this.loading$ = this.store.select(getLoading);
  }

  fetchRetry() {
    this.retrySubject$.next(false);
  }
}

This line in ngOnInit cause unnecessary api call. this.teams$ = this.store.select(getTeams);

How can I prevent it so that it makes the api call one time when initializing the app?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

平定天下 2025-01-31 15:19:18
loadTeams$ = createEffect(() => {
    return this.actions$.pipe(
      ofType(AuthActions.loadTeams),
      // read the actions$ for an load success event
      withLatestFrom(this.actions$.pipe(ofType(AuthActions.loadTeamsSuccess)),
      // no success event? no teams loaded, so go on
      filter(([loadTeamsAction, loadTeamsSuccessAction]) => !loadTeamsSuccessAction),
      // remove unnecessary action
      map(([loadTeams,]) => loadTeams),
      switchMap((action) =>
        this.apiService.teams$.pipe(
          tap(() => console.log('get teams request')),
          map((teams: Team[]) => AuthActions.loadTeamsSuccess({ teams })),
          catchError((error) => {
            console.log('err', error);
            return of(AuthActions.loadFailure({ error }));
          })
        )
      )
    );
  });
loadTeams$ = createEffect(() => {
    return this.actions$.pipe(
      ofType(AuthActions.loadTeams),
      // read the actions$ for an load success event
      withLatestFrom(this.actions$.pipe(ofType(AuthActions.loadTeamsSuccess)),
      // no success event? no teams loaded, so go on
      filter(([loadTeamsAction, loadTeamsSuccessAction]) => !loadTeamsSuccessAction),
      // remove unnecessary action
      map(([loadTeams,]) => loadTeams),
      switchMap((action) =>
        this.apiService.teams$.pipe(
          tap(() => console.log('get teams request')),
          map((teams: Team[]) => AuthActions.loadTeamsSuccess({ teams })),
          catchError((error) => {
            console.log('err', error);
            return of(AuthActions.loadFailure({ error }));
          })
        )
      )
    );
  });
甩你一脸翔 2025-01-31 15:19:18

在收到活动后阅读商店,然后过滤掉已经在商店中具有值的发出。

更多信息: https://timdeschryver.dev/blog/start-using-ngrx-effects-for-this/#enhance-your-actor-with-with-with-global-store-state

detail = createEffect(() => {
  return this.actions.pipe(
    ofType(ProductDetailPage.loaded),
    concatLatestFrom(() => this.store.select(selectProducts)),
    filter(([{ payload }, products]) => !!products[payload.sku]),
    mergeMap(([{payload}]) => {
      ...
    })
  )
})

Read the store after receiving the event, then filter out emits that already have a value in the store.

More info: https://timdeschryver.dev/blog/start-using-ngrx-effects-for-this/#enhance-your-action-with-global-store-state

detail = createEffect(() => {
  return this.actions.pipe(
    ofType(ProductDetailPage.loaded),
    concatLatestFrom(() => this.store.select(selectProducts)),
    filter(([{ payload }, products]) => !!products[payload.sku]),
    mergeMap(([{payload}]) => {
      ...
    })
  )
})
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文