#angular #angular-reactive-forms #angular-changedetection
#angular #angular-reactive-forms #angular-changedetection
Вопрос:
Мне было интересно, что происходит со следующим:
У меня есть FormGroup с этими элементами управления:
{
forename: new FormControl()
surname: new FormControl()
}
теперь я отслеживаю изменения «фамилии» элемента управления следующим образом (просто пример):
this.formGroup.get('surname').valueChanges.subscribe(changes => {
if(this.formGroup.get('forename') == 'Max'){
this.formGroup.get('forename').disable();
}
})
и в конце я исправляю свою форму следующим образом:
this.formGroup.patchForm({surname: 'Muster', forename: 'Max'});
Будет ли отключен элемент управления ‘forename’? Потому что я не уверен, что это вызовет изменение «фамилии» элемента управления до того, как он сможет установить значение элемента управления «forename». Поэтому ‘forename’, вероятно, еще не имеет ‘правильного’ значения.
Я пытаюсь лучше понять, когда запускаются события exactle valueChanges, так как иногда у меня возникает проблема, что значения не установлены, хотя они должны быть.
Мне также было интересно, можно ли дождаться, пока каждый элемент управления будет исправлен, а затем опубликовать изменения.
Комментарии:
1. попробуйте
valueChanges
для всего объекта формы. это сработает, если какое-либо значение в форме будет изменено, а затем вы можете использоватьfilter
оператор для фильтрации типа. что-то вродеthis.form.valueChanges.filter(x => x).subscribe(...)
2. Не уверен, как бы я сделал это для формы большего размера. Я могу сделать
this.formGroup.valueChanges.subscribe(changes =>....)
, что дало бы мне объект всех изменений, но тогда мне пришлось бы сравнить это с существующим объектом, чтобы определить, что на самом деле изменилось? У меня, вероятно, более 20 элементов управления, так что это не кажется хорошим решением. Не уверен, как я должен «фильтровать» его, поскольку нет чего-то вроде функции фильтра.3. Если я изменю порядок реквизитов в объекте обновления на:
{ forname: 'Max', surname: 'Muster' }
, то, похоже, все работает так, как задумано.
Ответ №1:
Причина:
valueChanges
for surname
сработает, как только patchValue()
обновит первое свойство, поэтому вы получите null
значение для forename
, а условие this.formGroup.get('forename') == 'Max'
будет false
.
Решение 1:
Вы можете subscribe()
использовать valueChanges
весь formGroup
элемент управления вместо одного, а затем проверить требуемое условие. Вот так:
this.formGroup
.valueChanges // subscribe to all changes
.pipe(
filter(form => form.forename === 'Max') // check if 'forname' is 'Max'
).subscribe(
forename => this.formGroup.get('forename').disable() // disable control
);
Решение 2:
Вы можете добиться желаемого поведения в своем коде, просто изменив порядок реквизитов в object для обновления. Вот так:
this.formGroup.patchForm({ forename: 'Max', surname: 'Muster' });
Комментарии:
1. Привет, спасибо за объяснение! На самом деле я рассматривал вариант решения 2, но я не хочу сталкиваться с ошибками только потому, что свойства в объекте не имеют определенного порядка.. Решение 1 также очень интересно! Наконец, я решил в основном указать другое значение Changes-Subscription в имени пользователя (я отвечу на свой собственный вопрос, чтобы продемонстрировать). Возможно, это не самый чистый вариант, но для моего проекта не было возможности перестроить все события valueChanges в соответствии с чем-то подобным первому решению.
Ответ №2:
Это то, что я закончил делать:
this.formGroup.get('surname').valueChanges.subscribe(changes => {
this.handleForenameControl();
})
this.formGroup.get('forename').valueChanges.subscribe(changes => {
this.handleForenameControl();
})
private handleForenameControl():void{
if(this.formGroup.get('forename') == 'Max'){
this.formGroup.get('forename').disable();
}
}
Я знаю, что это не самый чистый вариант, и я подумывал о том, чтобы не вводить другое значение Changes-Subscription, но да.
Я имею в виду, что выше был просто пример и не было кода, который я фактически использовал в проекте, поэтому пример может быть плохим. Может быть, это все еще кому-то помогает.
Комментарии:
1. разве это не то же самое, что решение 1 ответа? Я имею в виду подписку на изменение всех значений формы или подписку на изменение всех значений по отдельности? по крайней мере, в этом случае, когда элементов управления всего 2. и да, это не самый чистый способ, но если это работает для вас, а не часть реального проекта, то я думаю, что это хорошо 🙂
2. наконец, если бы вы могли объяснить, почему вы не хотите использовать решение 1, тогда, возможно, я смог бы обновить его по мере необходимости.