Установите значение вручную для элемента управления 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системы, поле остается пустым! Я видел другое использование updateValue()PPL, но это бета-версия 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-subscribe и загружало значение формы, но, устанавливая строку значения, выполняемую первой, подписка действительно выполнялась позже как асинхронная. поэтому, установив значение в подписке, убедитесь, что оно установлено. my2cents!
HydTechie

Ответы:

326

Обновлено: 19.03.2017

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

OLD:

На данный момент мы вынуждены сделать приведение типа:

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

Не очень элегантно, я согласен. Надеюсь, что это будет улучшено в будущих версиях.

Filoche
источник
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);
Джеймс Полус
но это не будет выполнять проверку новых данных !! Как вручную активировать обнаружение изменений после обновления?
КШ
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 final имеет обновленные 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"});
vivekkurien
источник
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 Doc относительно второго параметра 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);
chovy
источник
То же самое случилось со мной. Почему это так?
Рехманали Момин
3
  let cloneObj = Object.assign({}, this.form.getRawValue(), someClass);
  this.form.complexForm.patchValue(cloneObj);

Если вы не хотите вручную устанавливать каждое поле.

robottaxes
источник
2

@ Filoche's Angular 2 обновленное решение. С помощьюFormControl

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

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

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

В качестве альтернативы вы можете использовать решение @ AngularUniversity, которое используетpatchValue

zurfyx
источник
1

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

Ваша структура формы настолько идеальна, чтобы использовать ее в качестве примера. Итак, на протяжении всего моего ответа я буду обозначать его как форму.

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

поэтому наша форма представляет собой объект типа FormGroup, который имеет три FormControl .

Есть два способа обновить значение модели:

  • Используйте метод setValue (), чтобы установить новое значение для отдельного элемента управления. Метод setValue () строго придерживается структуры группы форм и заменяет все значение для элемента управления.

  • Используйте метод patchValue () для замены любых свойств, определенных в объекте, которые изменились в модели формы.

Строгие проверки метода setValue () помогают отследить ошибки вложения в сложных формах, в то время как patchValue () автоматически завершает работу с этими ошибками.

Из угловой официальной документации тут

Таким образом, при обновлении значения для экземпляра группы форм, который содержит несколько элементов управления, но вы можете захотеть обновить только части модели. 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;
}

когда вам нужно обновить элемент управления формы, просто используйте это свойство для его обновления. В этом примере спрашивающий пытался обновить элемент управления формы dept, когда пользователь выбирал элемент из выпадающего списка.

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 } );
Simon_Weaver
источник