Вручну встановити значення для управління FormBuilder


176

Це ганяє мене, я під рушницею і не можу дозволити собі витратити ще цілий день на це.

Я намагаюся вручну встановити контрольне значення ('dept') всередині компонента, і воно просто не працює - навіть нове значення записується, щоб консолірувати належним чином.

Ось екземпляр FormBuilder:

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

Це обробник подій, який отримує вибрану команду:

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

Тепер, коли форма подається, і я виходжу, this.formполе все ще залишається порожнім! Я бачив інше використання ppl, updateValue()але це beta.1, і я не вважаю це правильним методом для виклику управління.

Я також намагався зателефонувати updateValueAndValidity()без успіху :(.

Я просто використовував би ngControl="dept"елемент форми, як це я роблю з рештою форми, але власною директивою / компонентом.

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

Я зіткнувся з подібною ситуацією, сценарій полягав у тому, що значення було встановлене в http.get-підписатись та завантаження значення форми, але, встановивши рядок значень, який виконується спочатку, підписка дійсно виконується пізніше як її асинхронна. тому встановивши значення в підписці, переконайтесь, що його встановлено. my2cents!
HydTechie

Відповіді:


326

Оновлено: 19.03.2017

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

СТАРИЙ:

Наразі ми змушені робити акторський тип:

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

Я не дуже елегантний, я згоден. Сподіваюсь, це покращиться в майбутніх версіях.


6
Це прекрасно працює, дякую. Також потрібно підтвердити перевірку: (<Control>this.form.controls['dept']).setErrors(null)
Людина зателефонувала Хані

17
Або поки this.form.get('dept').setValue(selected.id):)
developer033

6
Просто записка. Ви також можете отримати доступ до ресурсу безпосередньо без індексатора. this.form.controls.dept.setValue(selected.id);
James Poulose

але це не виконає перевірку нових даних !! Як вручну запустити виявлення змін після оновлення?
КШ

1
Для мене це працює у 2019 році:this.form.controls['dept'].setValue(selected.id);
Джон Лопес

98

У Angular 2 Final (RC5 +) є нові API для оновлення значень форми. Метод patchValue()API підтримує часткові оновлення форми, де нам потрібно лише вказати деякі поля:

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

Існує також setValue()метод API, який потребує об'єкта з усіма полями форми. Якщо поле відсутнє, ми отримаємо помилку.


7
Просто додамо, що відтепер updateValue(з прийнятої відповіді Філоче) застаріла на користьsetValue
superjos

2
Ось офіційний запит на притягнення до Github та обґрунтування знецінення updateValue()та введення patchValueта setValue.
TheBrockEllis

але це не виконає перевірку нових даних !! Як вручну запустити виявлення змін після оновлення
ksh

16

Фінал Aangular 2 оновив API. Для цього вони додали багато методів.

Щоб оновити контроль форми від контролера, зробіть це:

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

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

Не потрібно скидати помилки

Список літератури

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

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


різниця між двома - setValue()при виклику на a formGroup/formBuilderвін вимагає встановлення всіх значень під формою. patchValue(), коли викликається те саме, може використовуватися для оновлення конкретних значень.
Vibhor Dube

11

Для оновлення значення контролю реактивної форми можна використовувати наступні методи. Будь-який із наведених методів підійде для ваших потреб.

Методи, що використовують setValue ()

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

Методи використання patchValue ()

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

Останній метод буде циклічно ремонтувати всі елементи управління у формі, тому його не бажано при оновленні одиничного контролю

Ви можете використовувати будь-який метод всередині обробника подій

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

Ви можете оновити кілька елементів управління у групі форм, якщо потрібно, використовуючи

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

9

Ви можете спробувати це:

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

Щоб отримати докладнішу інформацію, ви можете ознайомитись з відповідним документом JS щодо другого параметра updateValueметоду: https://github.com/angular/angular/blob/master/modules/angular2/src/common/forms/model. т.с. # L269 .


Дякуємо за вашу відповідь - однак updateValue, здається, не є дійсним методом у angular2 beta.1 - На якій версії ви користуєтесь цим методом?
Меттью Браун

1
Машинопис дає наступне повідомлення про помилку: error TS2339: Property 'updateValue' does not exist on type 'AbstractControl'. У цьому компоненті форма має тип ControlGroup. Можливо, якби я створив їх індивідуально, new Control()це допоможе
Меттью Браун

5

Жоден із них не працював на мене. Я повинен був зробити:

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

Те саме сталося і зі мною. Чому це так?
Рехманалі Момін

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

Якщо ви не хочете вручну встановити кожне поле.


2

@ Corlo 2 оновлене рішення Filoche. ВикористанняFormControl

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

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

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

Крім того, ви можете використовувати рішення AngularUniversity, яке використовуєpatchValue


1

Я знаю, що відповідь вже дана, але я хочу дати коротку відповідь, як оновити значення форми, щоб інші нові бажаючі могли отримати чітке уявлення.

ваша форма форми настільки досконала, щоб використовувати її як приклад. тож у всій своїй відповіді я позначатиму це як форму.

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

тому наша форма є об'єктом типу FormGroup, який має три FormControl .

Існує два способи оновлення значення моделі:

  • Використовуйте метод setValue () для встановлення нового значення для окремого елемента керування. Метод setValue () суворо дотримується структури групи форм і замінює все значення для елемента керування.

  • Використовуйте метод patchValue () для заміни будь-яких властивостей, визначених в об'єкті, які змінилися у формі форми.

Сувора перевірка методу setValue () допомагає вловлювати помилки введення в складні форми, в той час як patchValue () мовчки не відповідає цим помилкам.

З офіційної документації Angular тут

Отже, оновлюючи значення для екземпляра групи форм, який містить декілька елементів керування, але ви можете лише оновити частини моделі. patchValue () - це той, кого ви шукаєте.

давайте подивимось приклад. Коли ви використовуєте patchValue ()

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

але коли ви використовуєте setValue (), вам потрібно оновити повну модель, оскільки вона чітко дотримується структури групи форм. так, якщо ми пишемо

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

Ми повинні передати всі властивості моделі форми форми. подобається це

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

але я не використовую цей стиль часто. Я вважаю за краще використовувати наступний підхід, який допомагає зберегти чистіший і зрозуміліший код.

Що я роблю, я оголошую всі елементи управління окремою змінною і використовую setValue () для оновлення цього конкретного елемента управління.

для наведеної форми я зроблю щось подібне.

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

коли вам потрібно оновити контроль форми, просто скористайтеся цим властивістю, щоб оновити його. У прикладі запитуючий спробував оновити контроль форми форми, коли користувач вибирав предмет зі спадного списку.

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

Я пропоную ознайомитись з API FormGroup, щоб дізнатись про всі властивості та методи FormGroup.

Додатково : дізнатися про геттер дивіться тут


1

Якщо ви використовуєте контроль форми, то найпростіший спосіб зробити це:

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

-1

Порада: Якщо ви використовуєте, setValueале не надаєте кожну власність у формі, ви отримаєте помилку:

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

Тож ви можете спокуситись використовувати patchValue, але це може бути небезпечно, якщо ви намагаєтесь оновити цілу форму. У мене це addressможе бути stateOrProvinceабо не stateCdзалежно від того, чи це США, чи всьому світі.

Натомість ви можете оновити так, що використовуватиме нулі як стандартні:

this.form.setValue( { stateOrProvince: null, stateCd: null, ...address } );
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.