Mi clase de servicio, antes de llamar a un servicio web, necesita obtener una propiedad llamada dataForUpdate de mi estado. Actualmente, lo estoy haciendo así:
constructor(public _store: Store < AppState > , public _APIService: APIService) { const store$ = this._store.select('StateReducer'); .../... let update = this.actions$.filter(action => action.type == UPDATE) .do((action) => this._store.dispatch({ type: REDUCER_UPDATING, payload: action.payload })) ** * GET STATE ** *= => .mergeMap(action => store$.map((state: AppState) => state.dataForUpdate).distinctUntilChanged(), (action, dataForUpdate) { return { type: action.type, payload: { employee: action.payload, dataForUpdate: dataForUpdate } }; }) * AND CALL API *= => .mergeMap(action => this._APIService.updateEmployee(action.payload.employee, action.payload.dataForUpdate), (action, APIResult) => { return { type: REDUCER_UPDATED } }) .share(); .../... let all = Observable.merge(update, ....); all.subscribe((action: Action) => this._store.dispatch(action)); }Estoy usando angular2-store-example ( https://github.com/ngrx/angular2-store-example/blob/master/src/app/users/models/users.ts ) como guía a seguir.
Me pregunto si existe una forma mejor (más limpia).
Ejemplo en vivo: https://plnkr.co/edit/WRPfMzPolQsYNGzBUS1g?p=preview
@ngrx/store extiende BehaviorSubject y tiene una propiedad de value que puede usar.
this._store.valueese será el estado actual de su aplicación, y desde allí puede seleccionar propiedades, filtrar, mapear, etc.
actualizar:
Me tomó un tiempo averiguar qué es qué en su ejemplo (: para obtener el valor actual de dataForUpdate , puede usar:
let x = this._store.value.StateReducer.dataForUpdate; console.log(x); // => { key: "123" } Con la actualización a la versión 2, el value se eliminó como se describe en los documentos :
Se han eliminado las API para extraer sincrónicamente el valor de estado más reciente de Store. En cambio, siempre puede confiar en
subscribe()ejecutándose sincrónicamente si tiene que obtener el valor del estado:
function getState(store: Store<State>): State { let state: State; store.take(1).subscribe(s => state = s); return state; }Siguiendo la respuesta de @Sasxa, la sintaxis cambió en las versiones más nuevas de @nrgx/store (v5 y v6). Después de que la biblioteca RxJS subyacente se actualizó a ^5.5.0, ahora hay un método de tubería disponible en todas las instancias de Observable , lo que permite un encadenamiento más fácil y cambia la forma en que se logra una suscripción.
Así que ahora puedes hacer algo como:
import { take } from 'rxjs/operators'; function getState(store: Store<State>): State { let state: State; store.select('your-state').pipe(take(1)).subscribe( s => state = s ); return state; } O, usando estrictamente el operador pipe() :
import { select } from '@ngrx/store'; import { take } from 'rxjs/operators'; function getState(store: Store<State>): State { let state: State; store.pipe(select('your-state'), take(1)).subscribe( s => state = s ); return state; }Y si desea que su código sea un poco más legible, también puede emplear mecánicas asíncronas/en espera como esta:
import { select } from '@ngrx/store'; import { take } from 'rxjs/operators'; function async getStateAsync(store: Store<State>): State { let state = await store .pipe( select('your-state'), take(1) ) .toPromise<State>(); return state; }No es estrictamente una respuesta directa a la pregunta, pero encontré esta página buscando cómo recuperar un valor único de la tienda.
Para lograr esto, puede inyectar el objeto State desde @ngrx/store como se muestra a continuación:
import { State } from '@ngrx/store'; constructor (private state: State<AppState>) { let propertyValue = state.getValue().path.to.state.property; } El objeto de state contiene el estado actual en una propiedad _value privada, a la que se accede mediante el método .getValue() .