reactivos - Valor establecido de Angular2 para formGroup
ngmodel angular 5 (6)
Por lo tanto, tengo una forma compleja para crear una entidad y también quiero usarla para editar, estoy usando nuevas formas angulares API. Estructuré el formulario exactamente como los datos que recupero de la base de datos, por lo que quiero establecer el valor del formulario completo a los datos recuperados aquí, es un ejemplo de lo que quiero hacer:
this.form = builder.group({
b : [ "", Validators.required ],
c : [ "", Validators.required ],
d : [ "" ],
e : [ [] ],
f : [ "" ]
});
this.form.value({b:"data",c:"data",d:"data",e:["data1","data2"],f:data});
PD: NgModel no funciona con nuevos formularios api y tampoco me importa usar el enlace de datos unidireccional en la plantilla como en
<input formControlName="d" value="[data.d]" />
eso funciona pero sería un dolor en el caso de las matrices
"NgModel no funciona con nuevas formas api".
Eso no es cierto. Solo necesitas usarlo correctamente. Si está utilizando las formas reactivas, el NgModel debe usarse en concierto con la directiva reactiva. Vea el ejemplo en la fuente .
/*
* @Component({
* selector: "login-comp",
* directives: [REACTIVE_FORM_DIRECTIVES],
* template: `
* <form [formGroup]="myForm" (submit)=''onLogIn()''>
* Login <input type=''text'' formControlName=''login'' [(ngModel)]="credentials.login">
* Password <input type=''password'' formControlName=''password''
* [(ngModel)]="credentials.password">
* <button type=''submit''>Log in!</button>
* </form>
* `})
* class LoginComp {
* credentials: {login:string, password:string};
* myForm = new FormGroup({
* login: new Control(this.credentials.login),
* password: new Control(this.credentials.password)
* });
*
* onLogIn(): void {
* // this.credentials.login === "some login"
* // this.credentials.password === "some password"
* }
* }
*/
Aunque parece ser de los comentarios TODO , esto probablemente se eliminará y se reemplazará con una API reactiva.
// TODO(kara): Replace ngModel with reactive API
@Input(''ngModel'') model: any;
Como se señaló en los comentarios, esta característica no era compatible cuando se hizo esta pregunta. Este problema se ha resuelto en angular 2 rc5
He implementado una solución temporal hasta que angular2 soporte form updateValue
initFormGroup(form: FormGroup, data: any) {
for(var key in form.controls) {
console.log(key);
if(form.controls[key] instanceof FormControl) {
if(data[key]){
let control = <FormControl>form.controls[key];
this.initFormControl(control,data[key]);
}
} else if(form.controls[key] instanceof FormGroup) {
if(data[key]){
this.initFormGroup(<FormGroup>form.controls[key],data[key]);
}
} else if(form.controls[key] instanceof FormArray) {
var control = <FormArray>form.controls[key];
if(data[key])
this.initFormArray(control, data[key]);
}
}
}
initFormArray(array: FormArray, data: Array<any>){
if(data.length>0){
var clone = array.controls[0];
array.removeAt(0);
for(var idx in data) {
array.push(_.cloneDeep(clone));
if(clone instanceof FormGroup)
this.initFormGroup(<FormGroup>array.controls[idx], data[idx]);
else if(clone instanceof FormControl)
this.initFormControl(<FormControl>array.controls[idx], data[idx]);
else if(clone instanceof FormArray)
this.initFormArray(<FormArray>array.controls[idx], data[idx]);
}
}
}
initFormControl(control: FormControl, value:any){
control.updateValue(value);
}
uso:
this.initFormGroup(this.form, {b:"data",c:"data",d:"data",e:["data1","data2"],f:data});
nota: el formulario y los datos deben tener la misma estructura y he usado lodash para la clonación profunda, jQuery y otras bibliotecas también pueden hacerlo
Para establecer el uso de todos los valores de FormGroup , setValue :
this.myFormGroup.setValue({
formControlName1: myValue1,
formControlName2: myValue2
});
Para establecer solo algunos valores, use patchValue :
this.myFormGroup.patchValue({
formControlName1: myValue1,
// formControlName2: myValue2 (can be omitted)
});
Con esta segunda técnica, no se deben proporcionar todos los valores y los campos cuyos valores no se establecieron no se verán afectados.
Para establecer el valor cuando su control es FormGroup, puede usar este ejemplo
this.clientForm.controls[''location''].setValue({
latitude: position.coords.latitude,
longitude: position.coords.longitude
});
Sí, puede usar setValue para establecer el valor para fines de edición / actualización.
this.personalform.setValue({
name: items.name,
address: {
city: items.address.city,
country: items.address.country
}
});
Puede consultar http://musttoknow.com/use-angular-reactive-form-addinsert-update-data-using-setvalue-setpatch/ para comprender cómo usar los formularios reactivos para agregar / editar mediante el uso de setValue. Me ahorro tiempo