ngrx 仅当存储为空时才从服务器加载数据 [英] ngrx Load data from server only if the store is empty

查看:17
本文介绍了ngrx 仅当存储为空时才从服务器加载数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组静态数据,一个国家/地区列表,用于某些组件.这些数据是在这些组件的 ngOnInit() 上加载的,但我只想在我第一次请求数据时加载它们(存储是空的).以后每次我加载组件时,我都想简单地使用存储中的数据,而不是刷新"它.

I have a static set of data, a list of countries, that are used on some components. This data is loaded upon the ngOnInit() of these components but I'd like to load them only if it's the very first time that I request the data (the store is empty). Every subsequent times I load the component I'd like to simply use the data from the store without "refreshing" it.

如何使用 ngrx 实现这一点?

How is this achievable using ngrx?

我正在使用效果.这是我的代码的样子:

I'm using Effects. This is how my code looks like:

组件:

export class EditPageComponent implements OnInit {
countries$: Observable<Country[]>

constructor(private store: Store<fromContacts.State>) {
    this.countries$ = store.select(fromContacts.getCountriesEntities);
}
ngOnInit() {
   this.store.dispatch(new countries.Load());
}

效果:

    @Effect()
      loadCollection$: Observable<Action> = this.actions$
        .ofType(countries.LOAD)
        .switchMap(() =>
          this.countriesService
        .getCountries()
        .map((countriesList: Country[]) => {
          return new countries.LoadSuccess(countriesList);
        })
        .catch(error => of(new countries.LoadFail(error)))
  );

还有减速器:

case countries.LOAD_SUCCESS: {

      const countriesList: Country[] = action.payload;
      const reducedCountries: { [id: string]: Country } = countriesList.reduce((countrs: { [id: string]: Country }, countr: Country) => {
        return Object.assign(countrs, {
            [countr.code]: countr
        });
    }, {});

谢谢,加布

推荐答案

有不同的方法可以做到这一点.首先,您可以在状态中保留一个 hasLoaded: boolean 属性.然后,您可以在调用服务之前检查这一点.

There are different ways of doing this. First of all you can keep a hasLoaded: boolean property in the state. Then you can check this before you make the service get call.

ngOnInit() {
  this.store.select(getHasLoaded)
    .take(1)
    .subscribe(hasLoaded => {
      if (!hasLoaded) this.store.dispatch(new countries.Load()); 
    }
}

另一种选择是让您的@Effect 检查 hasLoaded 属性:

Another option is to let your @Effect check the hasLoaded property:

@Effect()
  loadCollection$: Observable<Action> = this.actions$
    .ofType(countries.LOAD)
    .withLatestFrom(this.store.select(getHasLoaded)
    .filter(([ action, hasLoaded ]) => !hasLoaded) // only continue if hasLoaded is false 
    .switchMap(() =>
      this.countriesService
        .getCountries()
        .map((countriesList: Country[]) => {
          return new countries.LoadSuccess(countriesList);
        })
    .catch(error => of(new countries.LoadFail(error)))
);

为此,您需要在效果构造函数中提供存储.

For this to work you need to provide the store in your Effects constructor.

这篇关于ngrx 仅当存储为空时才从服务器加载数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆