У меня есть angular веб-приложение, использующее angular материал. В моем 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 для динамических c элементов внутри ngFor ), я не могу получить доступ к компонентам, чтобы изменить их проверенное состояние.