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.