Estoy usando Angular2 - Formas reactivas. Todo funciona bien hasta que quiero mostrar un valor rellenado previamente en uno de los campos del Formulario.
Escenario: hay varios botones en una página y cada botón abre un formulario con campos como
Escenario fallido: el valor de entrada del código de producto se convierte en nulo.
Código TS:
import { FormGroup, FormBuilder, Validators } from '@angular/forms'; queryForm: FormGroup; constructor(private _productService: ProductService, fb: FormBuilder) { this.queryForm = fb.group({ 'name': [null, Validators.compose([Validators.required, Validators.minLength(5)])], 'email': [ null, [Validators.required, Validators.email] ], 'message': [null,Validators.compose([Validators.required, Validators.minLength(5)])], 'pcode': [ null ], }) }Formulario HTML:
<div *ngFor="let item of product"> <form action="#" [formGroup]="queryForm" (ngSubmit)="submitForm(queryForm.value)" method="post" novalidate="" class="text-left note" id="f_{{item.productId}}"> [ .... rest of the fields ...] <div class="form-group hidden"> <input type="hidden " class="form-control " id="pcode " name="pcode" formControlName="pcode" [value]="item.productCode" /> </div> <div class="form-group"> <button type="submit" class="btn1" [disabled]="!queryForm.valid">Submit</button> </div> </form> </div>¿Cómo puedo conseguir esto?
ACTUALIZACIÓN: Como descubrimos, necesita un formArray en lugar de un solo formControl . Así que declara que cuando construyas el formulario:
this.queryForm = this.fb.group({ arrayOfData: this.fb.array([]) // name a proper name to array }) Puede usar setValue o patchValue cuando haya recibido sus datos, donde itera la respuesta y parchea los valores en su matriz de formulario. Llame patchValues en su devolución de llamada (suscribirse).
patchValues() { const control = <FormArray>this.queryForm.get('arrayOfData'); this.items.forEach(x => { control.push(this.patchValue(x.first_name, x.pcode)) }) } patchValue(name, code) { return this.fb.group({ name: [name], pcode: [code] }) }En su plantilla, itere el formray y también recuerde establecer el formgroupname (que es el índice):
<div formArrayName="arrayOfData"> <div *ngFor="let code of queryForm.get('arrayOFData').controls; let i = index"> <div [formGroupName]="i"> <label>Name: </label> <input formControlName="name" /><br> <label>Product Code: </label> <input formControlName="pcode" /><br> </div> </div> </div>Respuesta original:
Siempre debe establecer los valores del formulario en el componente, no en la plantilla. Puede usar patchValue o setValue , cuando haya recibido el valor del servicio ... para que pueda hacer esto, por ejemplo, dentro de la devolución de llamada (suscribirse):
this.myService.getSomeData() .subscribe(data => { this.item = data; this.queryForm.patchValue({pcode: this.item.productCode}) }); Entonces no necesita usar [value]="item.productCode" en su formulario, este valor se establece con el control de formulario en su lugar.