web-dev-qa-db-fra.com

Angular2 valeur définie pour formGroup

J'ai donc un formulaire complexe pour créer une entité et je souhaite l'utiliser pour l'édition. J'utilise également une nouvelle API de formes angulaires. J'ai structuré le formulaire exactement comme les données extraites de la base de données. Par conséquent, je souhaite définir la valeur de l'ensemble du formulaire pour les données extraites ici. Voici un exemple de ce que je veux faire: 

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});

PS: NgModel ne fonctionne pas avec les nouveaux formulaires api, cela ne me dérange pas d'utiliser la liaison de données à sens unique dans le modèle comme dans 

<input formControlName="d" value="[data.d]" />

cela fonctionne mais ce serait une douleur en cas de tableaux

38
Amgad Serry

Pour définir toutes les valeurs du groupe de formes, utilisez setValue

this.myFormGroup.setValue({
  formControlName1: myValue1, 
  formControlName2: myValue2
});

Pour définir uniquement certaines valeurs, utilisez patchValue:

this.myFormGroup.patchValue({
  formControlName1: myValue1, 
  // formControlName2: myValue2 (can be omitted)
});

Avec cette seconde technique, toutes les valeurs ne doivent pas être fournies et les champs pour lesquels les valeurs n'ont pas été définies ne seront pas affectés.

148
Stephen Paul

Pour définir la valeur lorsque votre contrôle est FormGroup pouvez utiliser cet exemple

this.clientForm.controls['location'].setValue({
      latitude: position.coords.latitude,
      longitude: position.coords.longitude
    });
5
Sergiy Voytovych

Comme indiqué dans les commentaires, cette fonctionnalité n'était pas prise en charge au moment où cette question a été posée. Ce problème a été résolu dans angular 2 rc5 

3
Amgad Serry

Oui, vous pouvez utiliser setValue pour définir la valeur à des fins d'édition/mise à jour.

this.personalform.setValue({
      name: items.name,
      address: {
        city: items.address.city,
        country: items.address.country
      }
    });

Vous pouvez consulter http://musttoknow.com/use-angular-reactive-form-addinsert-update-data-using-setvalue-setpatch/ pour comprendre comment utiliser les formulaires réactifs pour ajouter/modifier des fonctions à l'aide de setValue . Ça m'a fait gagner du temps

2
Prashant M Bhavsar

J'ai implémenté une solution temporaire jusqu'à ce que angular2 support 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);
  }

usage:

this.initFormGroup(this.form, {b:"data",c:"data",d:"data",e:["data1","data2"],f:data});

note: la forme et les données doivent avoir la même structure et j'ai utilisé lodash pour le deepcloning jQuery et les autres bibliothèques peuvent aussi le faire 

2
Amgad Serry

"NgModel ne fonctionne pas avec les nouvelles formes api".

Ce n'est pas vrai. Vous avez juste besoin de l'utiliser correctement. Si vous utilisez les formes réactives, utilisez le NgModel de concert avec la directive réactive. Voir l'exemple dans la source

/*
 * @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"
 *  }
 * }
 */

Bien que cela apparaisse dans les commentaires de TODO , ceci sera probablement supprimé et remplacé par une API réactive.

// TODO(kara):  Replace ngModel with reactive API
@Input('ngModel') model: any;
0
Paul Samsotha