Valore impostato Angular2 per formGroup


94

Quindi ho un modulo complesso per creare un'entità e voglio usarlo anche per l'editing. Sto usando la nuova API di forme angolari. Ho strutturato il modulo esattamente come i dati che recupero dal database, quindi voglio impostare il valore dell'intero modulo sui dati recuperati qui è un esempio di quello che voglio fare:

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 non funziona con le nuove forme api, inoltre non mi dispiace usare l'associazione dati unidirezionale nel modello come in

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

funziona ma sarebbe una seccatura nel caso degli array


Per quanto ne so, l'impostazione di un valore per i moduli non è attualmente supportata e sarà supportata dopo il prossimo aggiornamento (RC.5). Fornisci un Plunker.
Günter Zöchbauer

@ GünterZöchbauer controlla la mia soluzione attuale
Amgad Serry

Risposte:


305

Per impostare tutti i valori di FormGroup utilizzare, setValue :

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

Per impostare solo alcuni valori, usa patchValue :

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

Con questa seconda tecnica, non è necessario fornire tutti i valori e i campi i cui valori non sono stati impostati non saranno interessati.


1
Sto usando patchValue in un modulo nidificato e sta sovrascrivendo tutti i campi nel modulo. (anche quelli che non ho specificato) idea di cosa sto sbagliando?
Enrico

@Enrico, senza il tuo codice non posso aiutarti.
molti altri

10

Per impostare il valore quando il controllo è FormGroup puoi utilizzare questo esempio

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

6

È possibile utilizzare form.get per ottenere l'oggetto di controllo specifico e utilizzare setValue

this.form.get(<formControlName>).setValue(<newValue>);

5

Sì, è possibile utilizzare setValue per impostare il valore a scopo di modifica / aggiornamento.

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

Puoi fare riferimento a http://musttoknow.com/use-angular-reactive-form-addinsert-update-data-using-setvalue-setpatch/ per capire come utilizzare i moduli reattivi per la funzione di aggiunta / modifica utilizzando setValue. Mi ha fatto risparmiare tempo


3

Come sottolineato nei commenti, questa funzione non era supportata al momento in cui è stata posta questa domanda. Questo problema è stato risolto in angular 2 rc5


2

Ho implementato una soluzione temporanea fino a quando updateValue del modulo di supporto angular2

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

utilizzo:

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

nota: modulo e dati devono avere la stessa struttura e ho usato lodash per la clonazione profonda di jQuery e anche altre librerie possono farlo


0

"NgModel non funziona con le nuove forme api".

Non è vero. Hai solo bisogno di usarlo correttamente. Se stai usando le forme reattive, il NgModel dovrebbe essere usato insieme alla direttiva reattiva. Vedi l'esempio nella fonte .

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

Sebbene sembri dai commenti TODO , questo verrà probabilmente rimosso e sostituito con un'API reattiva.

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

proveniente da angular2 api docs NgModel selector [ngModel]: not ([formControlName]): not ([formControl]) angular.io/docs/ts/latest/api/forms/index/… quindi anche se funziona ora lo sarà rimosso in seguito penso che implementerò un iniettore di valore manuale in quanto sarà una soluzione più stabile
Amgad Serry

@AmgadSerry che è per assicurarsi che non interferisca con quei componenti (nel selettore). Lo FormControlNameaggiunge esplicitamente come file @Input(). Vedi la fonte a cui mi sono collegato. Se quei selettori di negazione non fossero presenti, con l'esempio sopra, verrebbe creato un NgModel, che non vuoi.
Paul Samsotha

È un po 'confuso, ma è così che è implementato. Sia per FormControlDirective( [formControl]) che per FormControlName( formControlName), funziona così. Se ngModelviene utilizzato senza uno di questi, si presume che si utilizzeranno moduli dichiarativi e NgModelverrà creato un. Se ngModelviene utilizzato insieme a una delle direttive sulla forma reattiva , quella direttiva sulla forma reattiva gestirà il modello, non unNgModel
Paul Samsotha

oh, pensavo che l'avessero fatto come un trucco per abilitare ngModel su quelle due direttive solo per il momento e lo rimuoveranno più tardi
Amgad Serry

controlla la mia soluzione attuale
Amgad Serry
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.