Проблема
При добавлении радиосигналов к FormGroup
значение для FormControl
обновляется немедленно.Кроме того, изменение выбранной радиокнопки не приводит к обновлению значения FormControl
.
Код
Мой код - это система динамических форм, использующая службу (FormService
) для поддержки одиночного кода.FormGroup
с функциями для добавления и удаления входных данных по мере необходимости.
Все мои входные данные расширяют базовый входной класс с именем InputBaseComponent
, который импортирует FormService
, создает для себя элемент управления формой и добавляет его в FormGroup
через сервис.InputBaseComponent
также содержит все общие функциональные возможности, которые одинаковы для всех входных данных.
FormService
Сервис форм - это довольно универсальный сервис, который регулирует FormGroup
с помощью getter/ Сеттер функции.Эта услуга импортируется InputBaseComponent
, который расширяется каждым отдельным компонентом ввода.
import { Injectable } from '@angular/core';
import { FormGroup } from '@angular/forms';
@Injectable()
export class FormService {
// An arry of all the inputs in the form
inputs: any[] = [];
// The form group for this instance of the form service singleton
formGroup: FormGroup = new FormGroup({});
// Adds an input to the array of inputs in the form
addInput( input: any ){
// Push the input to the array if it's not already in the inputs array
if ( this.inputs.indexOf(input) === -1 ) this.inputs.push(input);
// Push the input's form control to the form group if it doesn't already exist
if ( !this.formGroup.contains(input.name) ) this.formGroup.addControl(input.name, input.formControl);
}
// Removes an input from the array of inputs in the form
removeInput( input: any ){
// Remove the input from the array if it exists
this.inputs.filter( arrayInput => arrayInput !== input);
// Remove the control from the form group
if ( this.formGroup.contains(input.name) ) this.formGroup.removeControl(input.name);
}
}
BaseInputComponent
Это базовый компонент ввода, который расширяют все действительные компоненты ввода.Это сделано для того, чтобы сохранить все общие функциональные возможности в одном месте, чтобы не повторять код для каждого ввода.Для простоты я обрезал все входные данные в конце, но, поверьте мне, они есть.
// ---------- Imports ---------- //
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { FormControl, Validators, ValidatorFn } from "@angular/forms";
/// ---------- Dependencies ---------- ///
import { FormService } from "../form.service";
// ---------- Components ------- //
@Component({
selector: 'input-base-component-do-not-use-directly',
template: ``
})
export class InputBaseComponent implements OnInit {
/// ---------- Constructor ---------- ///
constructor ( public formService: FormService ){};
/// ---------- Properties ----------- ///
// A reference to this form input's form control
formControl: any;
/// ---------- Methods -------------- ///
// On init set up the form control with the proper validators
ngOnInit() {
// Setup the form control with the proper validators
this.setupFormControl( this.getValidators() );
}
// Creates an array of all of the validator functions that should apply to the input and returns it
getValidators(): ValidatorFn[] {
// Create the validators array
let validators: any[] = [];
// Set the max length validator
if (this.maxLength) validators.push(Validators.maxLength(this.maxLength));
// Set the min length validator
if ( this.minLength ) validators.push(Validators.minLength(this.minLength));
// Set the required validator
if ( this.required ) validators.push(Validators.required);
// Include any custom validators
if ( this.customValidators && this.customValidators.length ) validators = validators.concat(this.customValidators);
// Return the array of validator functions
return validators;
}
// Sets up the form control and adds it to the form service
setupFormControl( validators: ValidatorFn[] ): void {
// Create the form control for this input
if (this.formService.formGroup.contains(this.name)) {
this.formControl = this.formService.formGroup.get(this.name)
} else {
this.formControl = this.getNewFormControl( validators );
this.formService.addInput(this);
}
// Update the parent component whenever this input's value is changed
this.formControl.valueChanges.subscribe( newValue => this.valueChange.emit(newValue));
// Add the input to the form group
this.formService.addInput(this);
}
// Takes an array of validator functions and returns a new form control with all of the proper setup for this input
getNewFormControl( validators: ValidatorFn[] ): FormControl {
// Return a new form control for this form
return new FormControl( this.value || null, { validators: validators, updateOn: this.validateOn } );
}
}
Код интереса
Если вы посмотрите на следующие строки setupFormControl
функция, которую вы можете видеть, что мы проверяем FormGroup
, чтобы увидеть, существует ли уже FormControl
с именем, заданным для входа, как в случае с переключателями и флажками.Если он уже существует, он использует этот существующий FormControl
в качестве элемента управления формы для ввода.Это было сделано, чтобы имитировать правильную разметку для использования переключателей и флажков с реактивными формами, где-в каждом переключателе или флажке в группе используется один и тот же элемент управления формой.
// Create the form control for this input
if (this.formService.formGroup.contains(this.name)) {
this.formControl = this.formService.formGroup.get(this.name)
} else {
this.formControl = this.getNewFormControl( validators );
this.formService.addInput(this);
}
Разметка, реализующая этот код, имеет видследует:
<!-- input -->
<input
#input
[formControl]="formControl"
[type]="type"
[name]="name"
[id]="idStr"
[value]="value"
tabindex="-1"
/>
Возможное решение
Как указывалось ранее, с этой настройкой, как только элемент управления формой добавляется (или повторно используется на тех, кто находится после первого радио / флажка),значение экземпляра FormControl
обновляется до последнего добавленного радио или флажка.Кроме того, каждый раз, когда изменяется выбранная радиостанция или флажок (и), значение FormControl
не обновляется.
Требуемая функциональность
Желаемая функциональность здесь заключается в том, что FormControl
свойство value
экземпляра будет оставаться как null
, пока пользователь не выберет радио или флажок.Кроме того, при изменении выбранного радио или флажка (ов) значение FormControl
должно обновиться.