Ręcznie ustaw wartość dla kontrolki FormBuilder

175

To doprowadza mnie do szału, jestem pod pistoletem i nie mogę sobie pozwolić na spędzenie na tym kolejnego dnia.

Próbuję ręcznie ustawić wartość kontrolną („dept”) w ramach komponentu, ale to po prostu nie działa - nawet nowa wartość loguje się do konsoli.

Oto instancja FormBuilder:

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

Oto procedura obsługi zdarzeń, która odbiera wybrany dział:

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

Teraz, gdy formularz jest przesyłany i wylogowuję się, this.formpole jest nadal puste! Widziałem inne użycie ppl, updateValue()ale to jest beta.1 i nie uważam tego za prawidłową metodę wywoływania formantu.

Próbowałem też zadzwonić updateValueAndValidity()bez powodzenia :(.

Po prostu użyłbym ngControl="dept"na elemencie formularza, tak jak robię to z resztą formularza, ale jest to niestandardowa dyrektywa / komponent.

<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>
Matthew Brown
źródło
Miałem podobną sytuację, scenariusz był taki, że wartość została ustawiona w http.get-subscribe i załaduj wartość formularza, ale ustawiając linię wartości, która ma być wykonywana jako pierwsza, subskrypcja naprawdę zostanie wykonana później jako asynchroniczna. więc ustawiając wartość w subskrypcji upewnij się, że jest ustawiona. my2cents!
HydTechie

Odpowiedzi:

325

Zaktualizowano: 19/03/2017

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

STARY:

Na razie jesteśmy zmuszeni wykonać rzut typu:

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

Zgadzam się niezbyt eleganckie. Mam nadzieję, że to zostanie ulepszone w przyszłych wersjach.

Filoche
źródło
6
To dobrze działa, dzięki. Muszę również wyczyścić walidację: (<Control>this.form.controls['dept']).setErrors(null)
Mężczyzna wezwany Haney
17
Albo jeszcze this.form.get('dept').setValue(selected.id):)
developer033
6
Tylko uwaga. Możesz również uzyskać dostęp do właściwości bezpośrednio bez indeksatora. this.form.controls.dept.setValue(selected.id);
James Poulose
ale to nie wykona walidacji dla nowych danych !! Jak ręcznie uruchomić wykrywanie zmian po aktualizacji?
ksh
1
To dla mnie 2019, to działa:this.form.controls['dept'].setValue(selected.id);
John Lopez
98

W Angular 2 Final (RC5 +) są nowe API do aktualizacji wartości formularzy. Metoda patchValue()API obsługuje częściowe aktualizacje formularzy, gdzie musimy tylko określić niektóre pola:

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

Istnieje również setValue()metoda API, która wymaga obiektu ze wszystkimi polami formularza. Jeśli brakuje pola, pojawi się błąd.

Uniwersytet Angular
źródło
7
Wystarczy dodać, że od teraz updateValue(od przyjętych Odpowiedź Filoche) jest zastąpionasetValue
superjos
2
Oto oficjalne żądanie ściągnięcia na Githubie oraz uzasadnienie wycofania updateValue()i wprowadzenia patchValueoraz setValue.
TheBrockEllis
ale to nie wykona walidacji dla nowych danych !! Jak ręcznie wywołać wykrywanie zmian po aktualizacji
ksh
16

Aangular 2 final zaktualizował API. Dodali do tego wiele metod.

Aby zaktualizować formant formularza z kontrolera, wykonaj następujące czynności:

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

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

Nie ma potrzeby resetowania błędów

Bibliografia

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

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

tanveer ahmad dar
źródło
różnica między nimi - setValue()wywołanie a formGroup/formBuilderwymaga ustawienia wszystkich wartości pod formularzem. patchValue(), gdy zostanie wywołany w ten sam sposób, może służyć do aktualizacji określonych wartości.
Vibhor Dube
11

Aby zaktualizować wartość kontrolki formularza reaktywnego, można użyć następujących metod. Każda z poniższych metod będzie odpowiednia dla twoich potrzeb.

Metody używające setValue ()

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

Metody wykorzystujące patchValue ()

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

Ostatnia metoda zapętli wszystkie kontrolki w formularzu, więc nie jest preferowana podczas aktualizowania pojedynczej kontrolki

Możesz użyć dowolnej metody wewnątrz procedury obsługi zdarzeń

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

W razie potrzeby możesz zaktualizować wiele kontrolek w grupie formularzy przy użyciu

this.form.patchValue({"dept": selected.id, "description":"description value"});
vivekkurien
źródło
9

Możesz spróbować tego:

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

Aby uzyskać więcej informacji, możesz rzucić okiem na odpowiedni dokument JS dotyczący drugiego parametru updateValuemetody: https://github.com/angular/angular/blob/master/modules/angular2/src/common/forms/model. ts # L269 .

Thierry Templier
źródło
Dziękuję za odpowiedź - jednak updateValue nie wydaje się być poprawną metodą w angular2 beta.1 - W której wersji jesteś w stanie użyć tej metody?
Matthew Brown
1
Maszynopis podaje następujący błąd: error TS2339: Property 'updateValue' does not exist on type 'AbstractControl' . W tym komponencie formularz ma typ ControlGroup. Być może, gdybym utworzył je indywidualnie new Control(), zadziałałoby
Matthew Brown
5

Żaden z nich nie działał dla mnie. Musiałem zrobić:

  this.myForm.get('myVal').setValue(val);
chovy
źródło
To samo stało się ze mną. Dlaczego tak się dzieje?
Rehmanali Momin
3
  let cloneObj = Object.assign({}, this.form.getRawValue(), someClass);
  this.form.complexForm.patchValue(cloneObj);

Jeśli nie chcesz ręcznie ustawiać każdego pola.

robottaxes
źródło
2

@ Zaktualizowano rozwiązanie Filoche's Angular 2. Za pomocąFormControl

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

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

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

Alternatywnie możesz skorzystać z rozwiązania @ AngularUniversity, które wykorzystujepatchValue

zurfyx
źródło
1

Wiem, że odpowiedź została już udzielona, ​​ale chcę udzielić krótkiej odpowiedzi, jak zaktualizować wartość formularza, aby inni nowi użytkownicy mogli uzyskać jasny pomysł.

Twoja struktura formularza jest tak idealna, aby użyć jej jako przykładu. tak więc w całej mojej odpowiedzi będę oznaczał to jako formę.

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

więc nasz formularz jest obiektem typu FormGroup, który ma trzy FormControl .

Istnieją dwa sposoby aktualizacji wartości modelu:

  • Użyj metody setValue (), aby ustawić nową wartość dla indywidualnej kontrolki. Metoda setValue () ściśle odpowiada strukturze grupy formularzy i zastępuje całą wartość kontrolki.

  • Użyj metody patchValue (), aby zastąpić wszelkie właściwości zdefiniowane w obiekcie, które uległy zmianie w modelu formularza.

Ścisłe sprawdzenia metody setValue () pomagają wychwycić błędy zagnieżdżania w złożonych formularzach, podczas gdy patchValue () po cichu zawodzi w przypadku tych błędów.

Z oficjalnej dokumentacji Angulara tutaj

tak więc podczas aktualizowania wartości dla wystąpienia grupy formularzy, które zawiera wiele kontrolek, ale możesz chcieć zaktualizować tylko części modelu. patchValue () jest tym, którego szukasz.

zobaczmy przykład. Kiedy używasz patchValue ()

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

ale kiedy używasz setValue () , musisz zaktualizować pełny model, ponieważ ściśle odpowiada on strukturze grupy formularzy. więc jeśli napiszemy

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

Musimy przekazać wszystkie właściwości modelu grupy formularzy. lubię to

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

ale nie używam tego stylu często. Wolę stosować następujące podejście, które pomaga zachować czystość i czytelność kodu.

To co robię, to deklaruję wszystkie kontrolki jako osobną zmienną i używam setValue () do aktualizacji tej konkretnej kontrolki.

dla powyższego formularza zrobię coś takiego.

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

kiedy musisz zaktualizować kontrolkę formularza, użyj tej właściwości, aby ją zaktualizować. W przykładzie pytający próbował zaktualizować kontrolkę formularza działu, gdy użytkownik wybierze pozycję z rozwijanej listy.

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

Proponuję rzucić okiem na FormGroup API, aby poznać wszystkie właściwości i metody FormGroup.

Dodatkowe : aby dowiedzieć się więcej o getter, zajrzyj tutaj

Sadid Khan
źródło
1

Jeśli używasz kontroli formularzy, najprostszy sposób na zrobienie tego:

this.FormName.get('ControlName').setValue(value);
Raihan Ridoy
źródło
-1

Wskazówka: jeśli używasz, setValueale nie podajesz wszystkich właściwości w formularzu, pojawi się błąd:

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

Możesz więc ulec pokusie patchValue, ale może to być niebezpieczne, jeśli próbujesz zaktualizować cały formularz. Mam, addressże może nie mieć stateOrProvincelubstateCd zależności od tego, czy jest to USA czy świat.

Zamiast tego możesz zaktualizować w ten sposób - co spowoduje użycie wartości null jako wartości domyślnych:

this.form.setValue( { stateOrProvince: null, stateCd: null, ...address } );
Simon_Weaver
źródło