Здесь есть две проблемы - одна связана с переключением между взаимоисключающими опциями (переключатели) и несколькими опциями (флажки). Другой связан с привязкой к объекту или массиву.
Вот блиц с решением: https://radio-group-example-solution.stackblitz.io
Управление радиокнопками и флажками в том же виджете
Во-первых, у меня есть массив параметров в компоненте, который выглядит следующим образом:
options: Option[] = [
{ name: 'Geddy Lee', id: 'GL' },
{ name: 'Alex Lifeson', id: 'AL' },
{ name: 'Neil Peart', id: 'RP' }
];
Существует также переменная selectedOptions, к которой компонент привязывается. Функция ngOnInit () устанавливает его следующим образом:
selectedOptions: Option | Option[];
...
ngOnInit(){
this.mutuallyExclusive = true;
this.selectedOptions = this.options[2];
}
Здесь this.selectedOptions
может быть либо объектом Option, либо массивом объектов Option. В этом случае я установил значение каждого mat-radio-button
как объект. mat-radio-group
обновляет связанную переменную значением переключателя - в данном случае это объект Option.
Виджет mat-selection-list
, который я использую для флажков, однако связывает не объект, а массив объектов. Он обновляет массив для включения набора выбранных объектов. В первую очередь я столкнулся с этой проблемой, пытаясь отследить, является ли this.selectedOptions
объектом или массивом объектов.
Вместо этого this.selectedOptions
всегда проще быть массивом. Привязать mat-radio-group
к первому месту в этом массиве, например:
<mat-radio-group name="ralph" [(ngModel)]="selectedOptions[0]">
<mat-radio-button *ngFor="let option of options" [value]="option">
{{ option.name }}
</mat-radio-button>
</mat-radio-group>
Таким образом, мой компонент легче читать, потому что я могу избавиться от логики c, связанной с выяснением того, привязываюсь к объекту или массиву. Поэтому, если вы имеете дело с обоими видами виджетов в одном компоненте, это один из способов управления им.
Установка выбранных переменных по ссылке
Другая проблема заключалась в том, что я пытался установите значение из компонента, установив его для объекта с теми же ключами и значениями, а не используя ссылку на исходные параметры.
Даже если объект идентичен с точки зрения его ключей и значений, Angular Материал не считает его тем же объектом. Если ваш набор опций исходит из массива, чтобы установить его программно, вам нужно сделать это, указав на фактическую опцию, а не на ее идентичный клон. Таким образом, это приводит к тому, что элементы управления должным образом отражают значение связанной переменной:
private changeToGeddy() {
let weinrib = this.options[0];
this.selectedOptions = [weinrib];
}
Функция короче и проще для чтения, потому что мы всегда привязываемся к массиву. (Нам не нужен оператор let
, но он подчеркивает тот факт, что мы устанавливаем его по ссылке, а не по объекту.)