Using ngrx to obtain store's current state onc

2020-04-05 08:19发布

问题:

Hi I was wondering if anyone know how to get a store's current state once without having to subscribe to it. I'm currently using ngrx to subscribe to the store and access its state to set a component's attribute, but since I'm subscribed this attribute is constantly refreshing. So I'm looking for a way to obtain this attribute just once so that I can display data without it refreshing constantly.

Just in case, this happens inside my component's constructor.

I've been trying something like this:

_store.select('storeData.correlationData');

When subscribing I would access like this:

_store.subscribe(
  (state) => {
    this.correlationData = state.storeData.correlationData;
  }
);

EDIT

Applciation State:

export interface ApplicationState {
  uiState: UiState;
  storeData: StoreData;
}

回答1:

You can create getState() function, put it in a shared module and import where needed. The key is to make it synchronous by using take(1) operator:

export function getState(store: any, selector: string) {
  let _state: any;
  store.take(1).subscribe(o => _state = o);
  return _state;
}

Here's more advanced version I'm using:

export function getState(store: any, selector?: any) {
  let _state: any;
  let state$: any;

  if (typeof selector === 'string' && /\./g.test(selector)) {
    state$ = store.pluck(...selector.split('.'));
  } else if (typeof selector === 'string') {
    state$ = store.map(state => state[selector]);
  } else if (typeof selector === 'function') {
    state$ = store.map(state => selector(state));
  } else {
    state$ = store;
  }
  state$.take(1)
    .subscribe(o => _state = o);
  return _state;
}

With this you can get state in few different ways:

getState(this.store) // all data in Store
getState(this.store, 'users')
getState(this.store, state => state.users)
getState(this.store, 'users.address.street') // Cool!

Use with caution!

As @Maximes pointed out in comments, you should try to use Observables directly in your code and use this method for testing.



标签: angular ngrx