tutorial example espaƱol forms angular redux rxjs

forms - example - Angular 2+ngrx(redux)+formas



ngrx store tutorial (4)

¿Cómo se manejan las formas angulares 2 en el flujo de datos unidireccional? ¿Especialmente con la validación entre varios componentes padre / hijo?

Estoy usando ngrx / store y model driven forms con form builder ... ¿Es posible hacer algo similar como form reducer en React y hacerlo como parte de Store?

¿Tienes algunos artículos sobre eso?


En las aplicaciones que construí con Angular 2, la siguiente guía parecía funcionar bien:

Los componentes principales transfieren datos a los niños a través del enlace de datos. Los componentes secundarios solicitan cambios de datos al emitir eventos de salida a los componentes principales. Es responsabilidad de los componentes de los padres actuar en consecuencia.

En una estructura jerárquica de componentes, los cambios de datos son manejados por el componente más bajo que depende de los datos. Si hay otro componente más arriba o un hermano que depende del mismo elemento de datos, pase cambios emitiendo eventos y deje el manejo a un componente más alto.

Este esquema funciona bien porque, para cualquier información que sea relevante para más de un componente, hay un único componente responsable de realizar cambios. Los cambios bajan automáticamente. Los componentes son reutilizables y los cambios en el árbol de componentes se pueden adaptar fácilmente.

Con respecto a la validación, cualquier componente en la escalera entre el componente más bajo que emite una solicitud de cambio de datos hasta el componente más alto que finalmente maneja el cambio, cualquier componente puede cancelar efectivamente el cambio al no pasarlo más arriba. Sin embargo, en la mayoría de las aplicaciones, optaría por validar los cambios en los datos en el origen del cambio.

Naturalmente, los componentes secundarios aún pueden tener un estado interno y no necesitan comunicar cambios, a menos que los cambios sean relevantes para el componente padre.


Esta es una pregunta bastante antigua, pero no pude encontrar una gran solución en mi propia búsqueda para trabajar con formas reactivas ngrx + en Angular. Como resultado, publicaré mi investigación aquí con la esperanza de que pueda ayudar a otra persona. Mi solución se puede dividir en dos partes, y le pido que (oh alma resistida) la encuentre aplicable a su problema:

1) Controle el / los elemento / s de formulario (por ejemplo, evento "keyup" para un ingreso de texto típico) y actualice el estado de ese evento. Esta estrategia viene directamente del componente de búsqueda de libros en la aplicación de ejemplo ngrx . Ahora podemos poblar con éxito el Estado a medida que cambia nuestro formulario. ¡Increíble! 50% hecho!

2) La guía de formas reactivas angulares demuestra la creación del grupo de formularios en el constructor. He visto a otras personas hacerlo dentro de ngOnInit, pero esto es demasiado tarde en el ciclo de vida para nuestras necesidades (lo intenté, fallé). Ahora que tenemos establecido nuestro grupo de formularios, configure ngOnChanges para capturar los cambios realizados desde el estado y luego actualice el grupo de formularios utilizando patchValue . Por ejemplo:

ngOnChanges(changes: SimpleChanges) { if (changes.valueICareAbout1) { this.myForm.patchValue({ valueICareAbout1: changes.valueICareAbout1.currentValue }); } if (changes.valueICareAbout2) { this.myForm.patchValue({ valueICareAbout2: changes.valueICareAbout2.currentValue }); } }


Los datos de formulario son intrínsecamente un estado muy local, especialmente para Angular, ya que ngModel se une a variables de componentes locales. Los principales desarrolladores que conozco recomiendan mantener los datos para el formulario localizado en ese componente (es decir, simplemente use ngModel con variables locales). Esto se debe a que los datos de formulario sin enviar casi nunca se comparten con varios componentes en toda su aplicación. Cuando el usuario envía el formulario, puede enviar una acción con una carga conteniendo los datos del formulario a un componente principal, a la tienda, o incluso a un ngrx / efecto que se publicará en un servidor.


ngrx-forms una biblioteca llamada ngrx-forms que hace exactamente lo que quiere. Puede obtenerlo en npm a través de:

npm install ngrx-forms --save

Recomiendo ver el archivo README completo en la página de github, pero a continuación puede encontrar algunos ejemplos de lo que debe hacer para que la biblioteca esté en funcionamiento una vez instalada.

Importar el módulo:

import { StoreModule } from ''@ngrx/store''; import { NgrxFormsModule } from ''ngrx-forms''; import { reducers } from ''./reducer''; @NgModule({ declarations: [ AppComponent, ], imports: [ NgrxFormsModule, StoreModule.forRoot(reducers), ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }

Agregue un estado de grupo en algún lugar de su árbol de estado a través de createFormGroupState y llame al formGroupReducer dentro de su reductor:

import { Action } from ''@ngrx/store''; import { FormGroupState, createFormGroupState, formGroupReducer } from ''ngrx-forms''; export interface MyFormValue { someTextInput: string; someCheckbox: boolean; nested: { someNumber: number; }; } const FORM_ID = ''some globally unique string''; const initialFormState = createFormGroupState<MyFormValue>(FORM_ID, { someTextInput: '''', someCheckbox: false, nested: { someNumber: 0, }, }); export interface AppState { someOtherField: string; myForm: FormGroupState<MyFormValue>; } const initialState: AppState = { someOtherField: '''', myForm: initialFormState, }; export function appReducer(state = initialState, action: Action): AppState { const myForm = formGroupReducer(state.myForm, action); if (myForm !== state.myForm) { state = { ...state, myForm }; } switch (action.type) { case ''some action type'': // modify state return state; default: { return state; } } }

Exponga el estado del formulario dentro de su componente:

import { Component } from ''@angular/core''; import { Store } from ''@ngrx/store''; import { FormGroupState } from ''ngrx-forms''; import { Observable } from ''rxjs/Observable''; import { MyFormValue } from ''./reducer''; @Component({ selector: ''my-component'', templateUrl: ''./my-component.html'', }) export class MyComponent { formState$: Observable<FormGroupState<MyFormValue>>; constructor(private store: Store<AppState>) { this.formState$ = store.select(s => s.myForm); } }

Establezca los estados de control en su plantilla:

<form novalidate [ngrxFormState]="(formState$ | async)"> <input type="text" [ngrxFormControlState]="(formState$ | async).controls.someTextInput"> <input type="checkbox" [ngrxFormControlState]="(formState$ | async).controls.someCheckbox"> <input type="number" [ngrxFormControlState]="(formState$ | async).controls.nested.controls.someNumber"> </form>