Мне удалось разработать рабочий пример того, чего вы пытаетесь достичь.Презентация является базовой, но она использует макет, идентичный вашему примеру кода.Я включил ссылку в самом низу моего решения.В основном это сводится к следующему коду.
component.ts
// inside of the component class
@ViewChildren(MatTreeNode, { read: ElementRef }) treeNodes: ElementRef[];
hasListener: any[] = [];
oldHighlight: ElementRef;
updateHighlight = (newHighlight: ElementRef) => {
this.oldHighlight && this.renderer.removeClass(this.oldHighlight.nativeElement, 'background-highlight');
this.renderer.addClass(newHighlight.nativeElement, 'background-highlight');
this.oldHighlight = newHighlight;
}
ngAfterViewChecked() {
this.treeNodes.forEach((reference) => {
if (!this.hasListener.includes(reference.nativeElement)) {
console.log('* tick');
this.renderer.listen(reference.nativeElement, 'click', () => {
this.updateHighlight(reference);
});
this.renderer.listen(reference.nativeElement.children.item(0), 'click', () => {
this.updateHighlight(reference);
});
this.hasListener = this.hasListener.concat([ reference.nativeElement ]);
}
});
this.hasListener = this.hasListener.filter((element) => document.contains(element));
console.log('*', this.hasListener.length);
}
component.css
.background-highlight {
background-color: whitesmoke;
}
Я разместил большую часть своей логики внутри ngAfterViewInit
крючок жизненного цикла.Это так, чтобы я мог получить доступ к результатам запроса @ViewChild
.Запрос возвращает ссылки на все элементы <mat-tree-node></mat-tree-node>
в шаблоне.Результаты сохраняются в this.treeNodes
как QueryList.
Я перебираю список.Я проверяю, есть ли у упомянутой nativeElement
уже прослушиватели событий.Слушатели событий срабатывают на мыши click
.Обратный вызов updateHighlight
обрабатывает удаление и добавление класса background-highlight
css, так что он остается уникальным в DOM.
Я добавил двух прослушивателей событий, нацеленных на <mat-tree-node></mat-tree-node>
и его вложенный элемент <button></button>
.Щелчок по обоим местам приводит к одинаковому выделению узла дерева.
В updateHighlight
Я удаляю класс background-highlight
из того места, где он был добавлен ранее (если применимо).Что бы ни нажималось в данный момент, получает класс background-highlight
.Ссылка на выбранный элемент заменяет предыдущее значение this.oldHighlight
.
Ради производительности я включил this.hasListener
.В массиве хранятся элементы <mat-tree-node></mat-tree-node>
, которые уже получили своих слушателей.Я могу проверить массив, чтобы убедиться, что я не перезаписываю слушателей без необходимости с каждым проходом ngAfterViewChecked
.
Последний бит логики удерживает this.hasListener
от выхода из-под контроля.Любые элементы, которые больше не подключены к DOM, больше не являются проблемой.
Я сохранил два оператора console.log
, потому что их выходные данные отражают, что код работает не только для выделения узлов дерева, по которым щелкнули.
Для любогодругие вопросы смотрите в репозитории: https://github.com/sosmaniac-FCC/mat-tree-node-example/tree/master/src/app/components/example-one.Я импортировал некоторые дополнительные утилиты из @angular/core
.
Конечно, если я где-то пропустил отметку, просто дайте мне знать.Я буду следить как можно лучше.