Демо Stackblitz (демо содержит немного больше информации, чем основы, описанные в предложении ниже).
Использование одного и того же экземпляра FormControl
, привязанного к нескольким компонентам, не является чем-то особенным Мне комфортно. Если вы разрешите мне предложение, которое BTW решает вашу проблему с начальным значением, не установленным в FormControl
: почему бы вам не использовать свой компонент, создав «RadioGroupControl» только для использования с формами , таким образом, чтобы вы могли связать FormControl
с группой, вместо того, чтобы делать это с отдельными элементами управления.
Что вы могли бы сделать:
1) Создайте LbRadioButtonGroupComponent
Его шаблон был бы очень простым:
selector: 'lb-radio-group-control',
template: '<ng-content></ng-content>'
Как говорит селектор, этот компонент предполагается использовать только для группировки радиокнопок внутри форм. Он должен работать просто как оболочка.
Внутри его машинописного текста возьмите все экземпляры RadioButtons.
@ContentChildren(RadioButtonComponent, { descendants: true })
_radioButtons: QueryList<RadioButtonComponent>;
Затем подпишитесь на эмиттер событий внутри каждого RadioButtonComponent
. Вам нужно будет передать больше, чем просто логическое значение, чтобы LbRadioButtonGroupComponent
мог установить для правого переключателя checked
состояние true
, когда вы получаете входящее значение (устанавливается хостом с помощью setValue()
, patchValue()
, или что-то вроде того). Я предлагаю свойство RadioButtonChange
, содержащее 2 атрибута: target
(нажатый input
) и value
(удобный атрибут, вы можете избавиться от него, если хотите). Итак, у нас есть:
ngAfterViewInit() {
const observableList: Observable<RadioButtonChange>[] = [];
this._radioButtons.map((rb: RadioButtonComponent) =>
observableList.push(rb.checkBoxClick));
merge(...observableList)
.pipe(
filter(Boolean),
takeUntil(this._destroy$)
)
.subscribe((value: any) => {
this._onTouch();
this._onChange(value ? value.value : null);
});
}
Тогда нам понадобится просто способ установить, какая кнопка в данный момент отмечена. Проблема здесь просто в сроках, потому что мы действительно не знаем, когда метод будет вызван для установки значения, и мы должны убедиться, что наш QueryList
уже был выполнен, а this._radioButtons
заполнен. Как только мы убедимся, что это произошло, следующий метод должен установить правый переключатель на checked
:
private _setGroupValue(value: any) {
this._radioButtons.forEach(
rb => (rb.radioButton.nativeElement.checked =
rb.radioButton.nativeElement.value === value)
);
}
2) Оберните RadioButtonComponent
s с RadioButtonGroupComponent
при использовании их в форме в качестве группы
После того, как у нас есть эти части, мы можем использовать наш компонент следующим образом:
<form [formGroup]="radioButtonForm">
<lb-radio-group-control formControlName="gender">
<p lb-radio-button [lbValue]="'Male'"
[lbRole]="'success'">
Male success radio button
</p>
<p lb-radio-button [lbValue]="'Female'"
[lbRole]="'info'">
Female info radio button
</p>
</lb-radio-group>
<div lb-button (buttonClick)="onSubmit()"
type="submit"
lbType="primary">Submit Form</div>
</form>
Поскольку у нас уже есть экземпляры lb-radio-button
s, нет необходимости устанавливать имя на них: мы можем сделать это в LbRadioButtonGroupComponent
. Конечно, вы можете сделать это таким образом, что не имеет значения, устанавливаете ли вы имя или устанавливаете разные имена для каждой радиокнопки (по ошибке).
Боковые примечания
В коде на Stackblitz вы найдете более полный код, содержащий некоторые проверки, такие как проверка, чтобы увидеть, нет ли внутри группы никаких RadioButtonComponent
привязан к FormControl
, или разработчик забыл привязать LbRadioButtonGroupComponent
к FormControl
.
Ну, это всего лишь общая идея, чтобы избежать привязки одного и того же FormControl
к нескольким компонентам в шаблон. Он не полный и требует таких вещей, как проверка формы, отключение элемента управления формой и возможность установить значение группы с помощью @Input() value
(я начал писать его в демонстрации, но я нахожусь в ru sh, и я думаю, что вы '' я уже понял суть).