Imposta manualmente il valore per il controllo FormBuilder


176

Questo mi sta facendo impazzire, sono sotto la pistola e non posso permettermi di passare un altro giorno intero su questo.

Sto cercando di impostare manualmente un valore di controllo ('dept') all'interno del componente e non funziona, anche i nuovi registri di valori per la console in modo corretto.

Ecco l'istanza di FormBuilder:

initForm() {
  this.form = this.fb.group({
    'name': ['', Validators.required],
    'dept': ['', Validators.required],
    'description': ['', Validators.required],
  });
}

Questo è il gestore eventi che riceve il reparto selezionato:

deptSelected(selected: { id: string; text: string }) {
  console.log(selected) // Shows proper selection!

  // This is how I am trying to set the value
  this.form.controls['dept'].value = selected.id;
}

Ora quando il modulo viene inviato e mi disconnetto this.formil campo è ancora vuoto! Ho visto altri ppl usare updateValue()ma questo è beta.1 e non lo vedo come un metodo valido per chiamare il controllo.

Ho anche provato a chiamare updateValueAndValidity()senza successo :(.

Vorrei solo utilizzare ngControl="dept"l'elemento del modulo, come sto facendo con il resto del modulo ma è una direttiva / componente personalizzata.

<ng-select
  [data]="dept"
  [multiple]="false"
  [items]="depts"
  (selected)="deptSelected($event)" <!-- This is how the value gets to me -->
  [placeholder]="'No Dept Selected'"></ng-select>

Mi ero imbattuto in una situazione simile, lo scenario era il valore impostato in http.get-iscriviti e carica il valore del modulo, ma impostando la riga del valore che viene eseguita per prima, l'abbonamento viene effettivamente eseguito successivamente come asincrono. quindi impostando il valore nella sottoscrizione assicurati che sia impostato. my2cents!
HydTechie,

Risposte:


326

Aggiornato: 19/03/2017

this.form.controls['dept'].setValue(selected.id);

VECCHIO:

Per ora siamo costretti a fare un cast di tipo:

(<Control>this.form.controls['dept']).updateValue(selected.id)

Non molto elegante, sono d'accordo. Spero che questo venga migliorato nelle versioni future.


6
Funziona bene, grazie. È inoltre necessario cancellare la convalida: (<Control>this.form.controls['dept']).setErrors(null)
Man Called Haney,

17
O ancora this.form.get('dept').setValue(selected.id):)
developer033

6
Solo una nota. Puoi anche accedere direttamente alla proprietà senza un indicizzatore. this.form.controls.dept.setValue(selected.id);
James Poulose,

ma questo non eseguirà la validazione per i nuovi dati !! Come attivare manualmente il rilevamento delle modifiche dopo l'aggiornamento?
ksh,

1
È il 2019 per me che funziona:this.form.controls['dept'].setValue(selected.id);
John Lopez,

98

In Angular 2 Final (RC5 +) ci sono nuove API per l'aggiornamento dei valori dei moduli. Il patchValue()metodo API supporta gli aggiornamenti dei moduli parziali, in cui è necessario specificare solo alcuni dei campi:

this.form.patchValue({id: selected.id})

Esiste anche il setValue()metodo API che richiede un oggetto con tutti i campi del modulo. Se manca un campo, avremo un errore.


7
Solo per aggiungere che fin d'ora updateValue(dalla risposta accettata da Filoche) è stato deprecato a favore disetValue
superjos

2
Ecco la richiesta di pull ufficiale su Github e la logica per deprecare updateValue()e introdurre patchValuee setValue.
TheBrockEllis,

ma questo non eseguirà la validazione per i nuovi dati !! Come attivare manualmente il rilevamento delle modifiche dopo l'aggiornamento
ksh

16

Aangular 2 final ha aggiornato le API. Hanno aggiunto molti metodi per questo.

Per aggiornare il controllo del modulo dal controller, procedere come segue:

this.form.controls['dept'].setValue(selected.id);

this.form.controls['dept'].patchValue(selected.id);

Non è necessario ripristinare gli errori

Riferimenti

https://angular.io/docs/ts/latest/api/forms/index/FormControl-class.html

https://toddmotto.com/angular-2-form-controls-patch-value-set-value


differenza tra i due: setValue()quando viene chiamato su a formGroup/formBuilder, richiede l'impostazione di tutti i valori nel modulo. patchValue(), quando chiamato sullo stesso, potrebbe essere utilizzato per aggiornare valori specifici.
Vibhor Dube,

11

È possibile utilizzare i seguenti metodi per aggiornare il valore di un controllo modulo reattivo. Uno dei seguenti metodi si adatta alle tue necessità.

Metodi che utilizzano setValue ()

this.form.get("dept").setValue(selected.id);
this.form.controls["dept"].setValue(selected.id);

Metodi che utilizzano patchValue ()

this.form.get("dept").patchValue(selected.id);
this.form.controls['dept'].patchValue(selected.id);
this.form.patchValue({"dept": selected.id});

L'ultimo metodo eseguirà il ciclo completo di tutti i controlli nel modulo, quindi non è preferibile quando si aggiorna il controllo singolo

È possibile utilizzare qualsiasi metodo all'interno del gestore eventi

deptSelected(selected: { id: string; text: string }) {
     // any of the above method can be added here
}

È possibile aggiornare più controlli nel gruppo di moduli, se necessario, utilizzando il

this.form.patchValue({"dept": selected.id, "description":"description value"});

9

Puoi provare questo:

deptSelected(selected: { id: string; text: string }) {
  console.log(selected) // Shows proper selection!

  // This is how I am trying to set the value
  this.form.controls['dept'].updateValue(selected.id);
}

Per maggiori dettagli, puoi dare un'occhiata al documento JS corrispondente relativo al secondo parametro del updateValuemetodo: https://github.com/angular/angular/blob/master/modules/angular2/src/common/forms/model. ts # L269 .


Grazie per la tua risposta - tuttavia updateValue non sembra essere un metodo valido in angular2 beta.1 - In quale versione sei in grado di utilizzare quel metodo?
Matthew Brown,

1
Carattere tipografico dà il seguente errore: error TS2339: Property 'updateValue' does not exist on type 'AbstractControl'. In quel componente, il modulo ha il tipo di ControlGroup. Forse se li creo individualmente con new Control()questo funzionerebbe
Matthew Brown,

5

Nessuno di questi ha funzionato per me. Ho dovuto fare:

  this.myForm.get('myVal').setValue(val);

Lo stesso è successo con me. Perché è così?
Rehmanali Momin,

3
  let cloneObj = Object.assign({}, this.form.getRawValue(), someClass);
  this.form.complexForm.patchValue(cloneObj);

Se non si desidera impostare manualmente ciascun campo.


2

@ Soluzione aggiornata Angular 2 di Filoche. utilizzandoFormControl

(<Control>this.form.controls['dept']).updateValue(selected.id)

import { FormControl } from '@angular/forms';

(<FormControl>this.form.controls['dept']).setValue(selected.id));

In alternativa puoi utilizzare la soluzione di @ AngularUniversity che utilizzapatchValue


1

So che la risposta è già stata data, ma voglio dare una breve risposta su come aggiornare il valore di un modulo in modo che altri nuovi arrivati ​​possano avere un'idea chiara.

la tua struttura del modulo è così perfetta da usarla come esempio. così, in tutta la mia risposta, lo indicherò come modulo.

this.form = this.fb.group({
    'name': ['', Validators.required],
    'dept': ['', Validators.required],
    'description': ['', Validators.required]
  });

così il nostro modulo è un FormGroup tipo di oggetto che ha tre FormControl .

Esistono due modi per aggiornare il valore del modello:

  • Utilizzare il metodo setValue () per impostare un nuovo valore per un singolo controllo. Il metodo setValue () aderisce strettamente alla struttura del gruppo di moduli e sostituisce l'intero valore per il controllo.

  • Utilizzare il metodo patchValue () per sostituire qualsiasi proprietà definita nell'oggetto che è stata modificata nel modello di modulo.

I severi controlli del metodo setValue () aiutano a rilevare gli errori di annidamento in forme complesse, mentre patchValue () fallisce silenziosamente su tali errori.

Dalla documentazione ufficiale angolare qui

pertanto, quando si aggiorna il valore per un'istanza del gruppo di moduli che contiene più controlli, ma è possibile che si desideri aggiornare solo parti del modello. patchValue () è quello che stai cercando.

vediamo esempio. Quando usi patchValue ()

this.form.patchValue({
    dept: 1 
});
//here we are just updating only dept field and it will work.

ma quando si utilizza setValue () è necessario aggiornare il modello completo poiché aderisce strettamente alla struttura del gruppo di moduli. quindi, se scriviamo

this.form.setValue({
    dept: 1 
});
// it will throw error.

Dobbiamo passare tutte le proprietà del modello del gruppo di moduli. come questo

this.form.setValue({
      name: 'Mr. Bean'
      dept: 1,
      description: 'spome description'
  });

ma non uso spesso questo stile. Preferisco usare il seguente approccio che aiuta a mantenere il mio codice più pulito e comprensibile.

Quello che faccio è, dichiaro tutti i controlli come una variabile separata e uso setValue () per aggiornare quel controllo specifico.

per il modulo sopra, farò qualcosa del genere.

get companyIdentifier(): FormControl {
    return this.form.get('name') as FormControl;
}

get dept(): FormControl {
    return this.form.get('dept') as FormControl;
}

get description(): FormControl {
    return this.form.get('description') as FormControl;
}

quando è necessario aggiornare il controllo del modulo, basta usare quella proprietà per aggiornarlo. Nell'esempio l'interrogatore ha provato ad aggiornare il controllo del modulo di reparto quando l'utente seleziona un elemento dall'elenco a discesa.

deptSelected(selected: { id: string; text: string }) {
  console.log(selected) // Shows proper selection!

  // instead of using this.form.controls['dept'].setValue(selected.id), I prefer the following.

  this.dept.setValue(selected.id); // this.dept is the property that returns the 'dept' FormControl of the form.
}

Suggerisco di dare un'occhiata all'API FormGroup per conoscere come tutte le proprietà e i metodi di FormGroup.

Ulteriori : per conoscere il getter vedere qui


1

Se si utilizza il controllo modulo, il modo più semplice per farlo:

this.FormName.get('ControlName').setValue(value);

-1

Suggerimento: se stai utilizzando setValuema non fornisci tutte le proprietà del modulo, visualizzerai un errore:

Must supply a value for form control with name: 'stateOrProvince'.

Quindi potresti essere tentato di usarlo patchValue, ma questo può essere pericoloso se stai cercando di aggiornare un intero modulo. Ho un addressche potrebbe non avere stateOrProvinceo stateCddipende dal fatto che sia negli Stati Uniti o in tutto il mondo.

Invece puoi aggiornare in questo modo - che utilizzerà i valori null come valori predefiniti:

this.form.setValue( { stateOrProvince: null, stateCd: null, ...address } );
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.