Почему я не могу установить значение радиогруппы Angular Material из моего компонента? - PullRequest
0 голосов
/ 06 февраля 2020

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

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

Вот Блиц с примером: https://radio-group-example.stackblitz.io

Когда он появляется впервые, он просит вас выбрать вашего любимого участника группы Ru sh. По умолчанию это Нил Пирт. Выберите того, кого хотите, и он покажет вам их имя наверху. Но если вы нажмете кнопку «Pick Geddy», вы увидите, что его имя отображается правильно, но не выбрана радиокнопка.

Is Geddy selected or not?

Кроме того, если вы переключаетесь с переключателей на флажки и возвращаетесь с помощью кнопки «Переключить виджеты», он очищает все выбранные элементы. Вы можете выбрать участников и увидеть их имена с помощью флажков, но если вы попробуете кнопку «Pick Geddy», вы увидите, что она показывает его имя, но ни один из флажков не установлен.

Вот Функция выбора Geddy:

private changeToGeddy() {
  let weinrib = { name: 'Geddy Lee', id: 'GL' };
  if (this.mutuallyExclusive) {
    this.selectedOptions = weinrib;
  } else {
    this.selectedOptions = [weinrib];
  }
}

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

1 Ответ

0 голосов
/ 06 февраля 2020

Здесь есть две проблемы - одна связана с переключением между взаимоисключающими опциями (переключатели) и несколькими опциями (флажки). Другой связан с привязкой к объекту или массиву.

Вот блиц с решением: 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, но он подчеркивает тот факт, что мы устанавливаем его по ссылке, а не по объекту.)

...