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

查看:75
本文介绍了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)))
);

要使其正常工作,您需要在Effects构造函数中提供商店.

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

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

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