Manuelles Festlegen des Werts für das FormBuilder-Steuerelement


173

Das macht mich verrückt, ich bin unter der Waffe und kann es mir nicht leisten, einen weiteren ganzen Tag damit zu verbringen.

Ich versuche, einen Steuerwert ('dept') innerhalb der Komponente manuell festzulegen, und es funktioniert einfach nicht - selbst die neuen Wertprotokolle werden ordnungsgemäß konsolidiert.

Hier ist die FormBuilder-Instanz:

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

Dies ist der Ereignishandler, der die ausgewählte Abteilung empfängt:

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

Jetzt, wenn das Formular gesendet wird und ich mich abmelde, ist this.formdas Feld immer noch leer! Ich habe andere Benutzer gesehen, updateValue()aber dies ist Beta.1 und ich sehe das nicht als gültige Methode, um das Steuerelement aufzurufen.

Ich habe auch versucht, updateValueAndValidity()ohne Erfolg anzurufen :(.

Ich würde nur ngControl="dept"für das Formularelement verwenden, wie ich es mit dem Rest des Formulars mache, aber es ist eine benutzerdefinierte Direktive / Komponente.

<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>

Ich war in eine ähnliche Situation geraten. Das Szenario war, dass der Wert in http.get-subscribe festgelegt und der Formularwert geladen wurde. Wenn Sie jedoch festlegen, dass die Wertzeile zuerst ausgeführt wird, wird das Abonnement später wirklich als asynchron ausgeführt. Wenn Sie also den Wert im Abonnement festlegen, stellen Sie sicher, dass er festgelegt ist. my2cents!
HydTechie

Antworten:


323

Aktualisiert: 19/03/2017

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

ALT:

Im Moment sind wir gezwungen, eine Typbesetzung durchzuführen:

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

Nicht sehr elegant stimme ich zu. Hoffe, dass dies in zukünftigen Versionen verbessert wird.


6
Das funktioniert gut, danke. Außerdem muss die Validierung gelöscht werden: (<Control>this.form.controls['dept']).setErrors(null)
Man Called Haney

17
Oder noch this.form.get('dept').setValue(selected.id):)
developer033

6
Nur eine Notiz. Sie können auch direkt ohne Indexer auf die Eigenschaft zugreifen. this.form.controls.dept.setValue(selected.id);
James Poulose

Dies führt jedoch keine Validierung für die neuen Daten durch !! Wie kann die Änderungserkennung nach dem Update manuell ausgelöst werden?
ksh

1
Es ist 2019 für mich, das funktioniert:this.form.controls['dept'].setValue(selected.id);
John Lopez

98

In Angular 2 Final (RC5 +) gibt es neue APIs zum Aktualisieren von Formularwerten. Die patchValue()API-Methode unterstützt teilweise Formularaktualisierungen, bei denen nur einige der Felder angegeben werden müssen:

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

Es gibt auch die setValue()API-Methode, die ein Objekt mit allen Formularfeldern benötigt. Wenn ein Feld fehlt, wird eine Fehlermeldung angezeigt.


7
Nur um hinzuzufügen, dass ab sofort updateValue(aus der akzeptierten Antwort von Filoche) zugunsten vonsetValue
Superjos

2
Hier ist die offizielle Pull-Anfrage zu Github und die Gründe für die Ablehnung updateValue()und Einführung von patchValueund setValue.
TheBrockEllis

Dies führt jedoch keine Validierung für die neuen Daten durch !! Wie man die Änderungserkennung nach dem Update manuell auslöst
ksh

16

Aangular 2 final hat APIs aktualisiert. Sie haben viele Methoden dafür hinzugefügt.

Gehen Sie folgendermaßen vor, um das Formularsteuerelement vom Controller zu aktualisieren:

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

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

Die Fehler müssen nicht zurückgesetzt werden

Verweise

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

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


Unterschied zwischen den beiden - setValue()Wenn a aufgerufen wird formGroup/formBuilder, müssen alle Werte unter dem Formular festgelegt werden. patchValue()kann bei gleichem Aufruf zum Aktualisieren bestimmter Werte verwendet werden.
Vibhor Dube

11

Mit den folgenden Methoden können Sie den Wert eines reaktiven Formularsteuerelements aktualisieren. Jede der folgenden Methoden entspricht Ihren Anforderungen.

Methoden mit setValue ()

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

Methoden mit patchValue ()

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

Die letzte Methode durchläuft alle Steuerelemente im Formular, sodass sie beim Aktualisieren eines einzelnen Steuerelements nicht bevorzugt wird

Sie können jede der Methoden im Ereignishandler verwenden

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

Sie können bei Bedarf mehrere Steuerelemente in der Formulargruppe mithilfe von aktualisieren

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

9

Sie könnten dies versuchen:

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

Weitere Informationen finden Sie im entsprechenden JS-Dokument zum zweiten Parameter der updateValueMethode: https://github.com/angular/angular/blob/master/modules/angular2/src/common/forms/model. ts # L269 .


Vielen Dank für Ihre Antwort - jedoch scheint updateValue in angular2 beta.1 keine gültige Methode zu sein. - Auf welcher Version können Sie diese Methode verwenden?
Matthew Brown

1
Typoskript gibt folgenden Fehler aus : error TS2339: Property 'updateValue' does not exist on type 'AbstractControl'. In dieser Komponente hat das Formular den Typ ControlGroup. Vielleicht new Control()würde es funktionieren, wenn ich sie individuell damit erstelle
Matthew Brown

5

Nichts davon hat bei mir funktioniert. Ich musste es tun:

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

Das gleiche passierte mit mir. Warum ist das so?
Rehmanali Momin

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

Wenn Sie nicht jedes Feld manuell einstellen möchten.


2

@ Filoches Angular 2 aktualisierte Lösung. Verwenden vonFormControl

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

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

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

Alternativ können Sie die verwendete Lösung von @ AngularUniversity verwendenpatchValue


1

Ich weiß, dass die Antwort bereits gegeben ist, aber ich möchte eine kurze Antwort geben, wie der Wert eines Formulars aktualisiert wird, damit andere Neuankömmlinge eine klare Vorstellung davon bekommen.

Ihre Formularstruktur ist so perfekt, dass Sie sie als Beispiel verwenden können. In meiner Antwort werde ich es als Form bezeichnen.

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

Unser Formular ist also ein Objekt vom Typ FormGroup mit drei FormControl .

Es gibt zwei Möglichkeiten, den Modellwert zu aktualisieren:

  • Verwenden Sie die Methode setValue (), um einen neuen Wert für ein einzelnes Steuerelement festzulegen. Die setValue () -Methode hält sich strikt an die Struktur der Formulargruppe und ersetzt den gesamten Wert für das Steuerelement.

  • Verwenden Sie die patchValue () -Methode, um alle im Objekt definierten Eigenschaften zu ersetzen, die sich im Formularmodell geändert haben.

Die strengen Überprüfungen der setValue () -Methode helfen dabei, Verschachtelungsfehler in komplexen Formen abzufangen, während patchValue () diese Fehler stillschweigend ausfällt.

Aus der offiziellen Angular-Dokumentation hier

Wenn Sie also den Wert für eine Formulargruppeninstanz aktualisieren, die mehrere Steuerelemente enthält, möchten Sie möglicherweise nur Teile des Modells aktualisieren. patchValue () ist das, wonach Sie suchen.

Mal sehen, Beispiel. Wenn Sie patchValue () verwenden

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

Wenn Sie jedoch setValue () verwenden , müssen Sie das vollständige Modell aktualisieren, da es die Struktur der Formulargruppe strikt einhält . Also, wenn wir schreiben

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

Wir müssen alle Eigenschaften des Formulargruppenmodells übergeben. so was

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

aber ich benutze diesen Stil nicht häufig. Ich bevorzuge den folgenden Ansatz, um meinen Code sauberer und verständlicher zu halten.

Ich deklariere alle Steuerelemente als separate Variable und aktualisiere dieses spezifische Steuerelement mit setValue ().

Für das obige Formular werde ich so etwas tun.

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

Wenn Sie das Formularsteuerelement aktualisieren müssen, verwenden Sie einfach diese Eigenschaft, um es zu aktualisieren. In diesem Beispiel hat der Fragesteller versucht, die Abteilungsformularsteuerung zu aktualisieren, wenn der Benutzer ein Element aus der Dropdown-Liste auswählt.

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.
}

Ich schlage vor, einen Blick auf die FormGroup-API zu werfen zu , um mehr über alle Eigenschaften und Methoden von FormGroup zu erfahren.

Zusätzlich : Informationen zu Getter finden Sie hier


1

Wenn Sie die Formularsteuerung verwenden, ist dies am einfachsten:

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

-1

Tipp: Wenn Sie alle Eigenschaften des Formulars verwenden, setValueaber nicht angeben, wird folgende Fehlermeldung angezeigt:

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

Sie könnten also versucht sein, es zu verwenden patchValue, aber dies kann gefährlich sein, wenn Sie versuchen, ein ganzes Formular zu aktualisieren. Ich habe eine address, die möglicherweise nicht hat stateOrProvinceoder davon stateCdabhängt, ob es sich um eine US-amerikanische oder eine weltweite handelt.

Stattdessen können Sie wie folgt aktualisieren - wobei die Nullen als Standard verwendet werden:

this.form.setValue( { stateOrProvince: null, stateCd: null, ...address } );
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.