storemodule installing español ngrx

installing - ngrx wikipedia



Cómo realizar múltiples operaciones/efectos/acciones relacionadas con ngrx/effects (4)

Estoy trabajando en una aplicación que está usando ngrx / store 1.5 junto con middleware thunk y estoy intentando moverme a ngrx / store 2.0 y ngrx / effects. Tengo un par de preguntas con respecto a cómo manejar múltiples acciones y / o efectos relacionados.

Me doy cuenta de que la "mentalidad" para los efectos contra los thunks es diferente y estoy tratando de entender las diferencias. He revisado las aplicaciones de ejemplo disponibles y no he encontrado nada que parezca lo que estoy intentando, así que tal vez todavía me estoy equivocando.

escenario 1

Aquí hay un efecto secundario para manejar la solicitud al servidor para iniciar sesión:

@Effect login$: any = this.updates$ .whenAction(LoginActions.LOGIN) .map(toPayload) .switchMap(payload => this.loginService.login(payload.user, payload.password) .map(result => this.actions.loginSuccess(value)) .catch((error) => Observable.of(this.loginError(error))) ));

Dado ese efecto colateral inicial, ¿cuál sería la forma "correcta" o "sugerida" de activar la navegación a una pantalla de "inicio" al iniciar sesión correctamente? Esto también podría generalizarse para simplemente activar una secuencia de acciones u operaciones.

Algunas opciones que he considerado:

(a) ¿Otro efecto desencadenado por el éxito de inicio de sesión, que desencadena una acción posterior para activar la navegación?

@Effect navigateHome$: any = this.updates$ .whenAction(LoginActions.LOGIN_SUCCEEDED) .mapTo(this.actions.navigateHome());

(b) ¿Otro efecto desencadenado por el éxito de inicio de sesión, que simplemente realiza la operación de navegación?

@Effect navigateHome$: any = this.updates$ .whenAction(LoginActions.LOGIN_SUCCEEDED) .do(this.navigateHome()) .filter(() => false);

(c) Concatenar una acción adicional a las emitidas por el efecto de inicio de sesión inicial? (muestra obviamente no es del todo correcto, pero da la idea)

@Effect login$: any = this.updates$ .whenAction(LoginActions.LOGIN) .map(toPayload) .switchMap(password => Observable.concat( this.loginService.login(passcode) .map(result => this.actions.loginSuccess(value)) .catch((error) => Observable.of(this.loginError(error))), Observable.of(this.actions.navigateHome()) ));

(d) ¿Otro?

Escenario 2

Considere un caso en el que se deban realizar varias solicitudes en secuencia y, a medida que cada solicitud comience, queremos actualizar el "estado" para que se puedan proporcionar comentarios al usuario.

Ejemplo de un thunk para algo parecido a eso:

multiphaseAction() { return (dispatch) => { dispatch(this.actions.updateStatus(''Executing phase 1''); this.request1() .flatMap(result => { dispatch(this.actions.updateStatus(''Executing phase 2''); return this.request2(); }) .flatMap(result => { dispatch(this.actions.updateStatus(''Executing phase 3''); return this.request3(); }) ... } }

Nuevamente, ¿cuál sería la forma "correcta" o "sugerida" de abordar esto al usar el enfoque de los efectos?

Éste en el que estoy más atascado, no estoy seguro de qué podría hacerse aparte de agregar algo de .do(this.store.dispatch(this.actions.updateStatus(...)) alguna manera ...


Estoy aprendiendo esto también.

¿Qué pasa si te envían al reductor cuando el primero en la cadena estaba hecho?

Algo como esto:

const myReducer = (state,action:Action) => { switch action.type { case : "my_first_step" : runfirststep(action.payload); case : "my_second_step": runsecondstep(action.payload); .... function runfirststep(data) { ... //bunch of stuff to do, //update something to display store.dispatch(''my_second_step''); }

etc.

El ejemplo ngrx hace esto en el archivo de efectos. Cuando se agrega o actualiza, ellos llaman a UPDATE_COMPLETE o algo similar, presumiblemente para que se pueda hacer alguna notificación.

Poco a poco me doy cuenta de lo grandes que serán los reductores en una aplicación moderadamente compleja.


La respuesta para el escenario de navegación es tu respuesta b

@Effect navigateHome$: any = this.updates$ .whenAction(LoginActions.LOGIN_SUCCEEDED) .do(this.router.navigate(''/home'')) .ignoreElements();

Explicación: Usted reacciona a LOGIN_SUCCESS, y como el enrutador no devuelve una nueva acción, debemos detener la propagación de la transmisión, lo cual hacemos filtrando todo.

Si olvida filtrar, el enrutador devuelve indefinido, lo que a su vez conducirá al reductor a reducir un valor indefinido, que generalmente da como resultado un puntero nulo cuando intenta leer el type de acción.

Otra forma de resolverlo es usar https://github.com/ngrx/router-store

Consulte la documentación sobre cómo agregar el router-store a su aplicación.

El mismo efecto ahora se verá así.

import { go } from ''@ngrx/router-store''; @Effect navigateHome$: any = this.updates$ .whenAction(LoginActions.LOGIN_SUCCEEDED) .map(() => go([''/home'']));

La acción go enviará una acción del enrutador que el enrutador reducirá y activará un cambio de ruta.


escenario 1

Considere si navigateHome debería cambiar el estado o no. Además, independientemente de si esta acción navigateHome se envía desde otros lugares para lograr lo mismo. Si es así, devolver una acción es el camino a seguir. Por lo tanto, la opción A.

En algunos casos, la opción B podría tener más sentido. Si navigateHome solo cambia la ruta, podría valer la pena considerarla.

Nota al ignoreElements : puede usar ignoreElements aquí en lugar del filter(() => false) .

Escenario 2

Sugeriría encadenar sus acciones aquí en múltiples efectos y dar retroalimentación al modificar el estado en el reductor para cada acción.

Por ejemplo:

@Effect() trigger$: Observable<Action> = this.updates$ .whenAction(Actions.TRIGGER) .do(() => console.log("start doing something here")) .mapTo(Actions.PHASE1); @Effect() phase1$: Observable<Action> = this.updates$ .whenAction(Actions.PHASE1) .do(() => console.log("phase 1")) .mapTo(Actions.PHASE2); @Effect() phase2$: Observable<Action> = this.updates$ .whenAction(Actions.PHASE2) .do(() => console.log("phase 2")) .ignoreElements();

Y dar su opinión al modificar el estado:

function reducer(state = initialState, action: Action): SomeState { switch (action.type) { case Actions.TRIGGER: { return Object.assign({}, state, { triggered: true }); } case Actions.PHASE1: { return Object.assign({}, state, { phase1: true }); } case Actions.PHASE2: { return Object.assign({}, state, { phase1: false, phase2: true }); } // ... } }


escenario 1

Opción A y B son buenas para ir, creo, pero tal vez la opción A es demasiado para la navegación. También puede usar directamente el enrutador en LoginActions.LOGIN si considera la navegación como parte de este efecto secundario.

Escenario 2

No hay nada de malo en encadenar @Effects . Envíe una acción (SET_1_REQUEST) que active su efecto A. el efecto A devuelve una acción (SET_1_SUCCESS) que su reductor recoge (ahora puede mostrar ese estado al usuario) y se capta con el efecto B.

Espero que esto tenga sentido.