Angular Material как выбрать компонент в JS

У меня есть угловое веб-приложение, использующее угловой материал. В моем HTML у меня есть два ButtonToggles, которые вы можете переключать с помощью простого обработчика событий щелчка, который я обрабатываю сам. Однако также должен быть способ переключать кнопки с помощью сочетания клавиш. У меня есть прослушиватель событий нажатия клавиш, который правильно перехватывает нажатие клавиши, но я понятия не имею, как я могу переключить связанную кнопку, потому что я не могу передать ее обработчику событий.

Вот мой html

  <mat-button-toggle-group [multiple]="schema.multi">
        <mat-button-toggle *ngFor="let label of schema.labels"
                           (click)="toggleAnnotation(label, localButton)"
                           [value]="label.name"
                           #localButton
                           [style.background-color]="localButton.checked == true ? label.backgroundColor : 'ghostwhite'">
          {{label.name}} ({{label.shortcut}})
        </mat-button-toggle>
  </mat-button-toggle-group>
</div>

И соответствующий машинописный текст:

import {Component, EventEmitter, HostListener, Input, OnChanges, Output, SimpleChanges} from '@angular/core';
import {Label} from '../sequence/models/label';
import {TagAssignment} from '../../../models/tag-assignment';
import {MatButtonToggle, MatButtonToggleGroup} from "@angular/material/button-toggle";


export class CategoricalTaggerSchema {
  multi: boolean; // can the user select multiple tags at once
  prompt: string; // message to display before showing the tagger document
  labels: Label[]; // categories to select from
}

@Component({
  selector: 'app-categorical',
  templateUrl: './categorical-tagger.component.html',
  styleUrls: ['./categorical-tagger.component.css']
})
export class CategoricalTaggerComponent implements OnChanges {
  @Input() config: TagAssignment = new TagAssignment(); // default to some value
  @Output() valueChange = new EventEmitter<string>();
  @Output() validChange = new EventEmitter<boolean>();
  @Input() disabled = false;

  schema: CategoricalTaggerSchema = {multi: false, prompt: '', labels: []};
  annotations = new Set<string>(); // much simpler then sequence tagging, just a list of named labels

  constructor() {}

  ngOnChanges(changes: SimpleChanges): void {
    if (changes.hasOwnProperty('config')) {
      this.schema = JSON.parse(this.config.tag_schema);
    }
  }

  toggleAnnotation(label: Label, localButton) {
    if (!this.disabled) {
      if (this.annotations.has(label.name)) {
        this.annotations.delete(label.name);
        localButton.checked = false;
      } else { // creating new annotation
        if (!this.schema.multi) { // only one annotation allowed
          this.annotations.clear();

        }
        this.annotations.add(label.name);
      }
    }
    this.emitChanges();
    console.log(this.annotations);
  }

  emitChanges() {
    this.valueChange.emit(this.getValue());
    this.validChange.emit(this.isValid());
  }

  @HostListener('document:keypress', ['$event'])
  handleKeyboardEvent(event: KeyboardEvent) {
    // detect keypress for shortcut
    for (const label of this.schema.labels) {
      if (label.shortcut === event.key) {
        this.toggleAnnotation(label, null);
        break;
      }
    }
  }

  getValue(): string {
    return JSON.stringify(Array.from(this.annotations));
  }

  isValid(): boolean {
    return (this.annotations.size > 0);
  }

  reset(): void {
    this.annotations.clear();
  }
}

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

РЕДАКТИРОВАТЬ: я пытался использовать ViewChild, но поскольку я не могу динамически инициализировать идентификаторы (angular viewChild для динамических элементов внутри ngFor), я не могу получить доступ к компонентам, чтобы изменить их проверенное состояние.


person rocks6    schedule 04.05.2020    source источник