Как динамически получить экземпляр атрибутированной директивы из элемента в коде

Мне интересно, есть ли способ получить экземпляр директивы для элемента DIV? Там много элементов div, и мне не хотелось бы обрабатывать список в компоненте.

<div class = "item"
     (click) = "func($event)"
     appBoardResize>
</div>
<div class = "item"
     (click) = "func($event)"
     appBoardResize>
</div>

Количество элементов div не ограничено, и я хотел бы получить экземпляр appBoardResize соответственно каждому элементу div в func().

НГ-версия: 17^

пожалуйста, поделитесь минимальным воспроизводимым кодом, а также объясните ожидаемый результат кода

Naren Murali 04.06.2024 08:18

Добавлен пример кода @NarenMurali. пожалуйста, рассматривайте appBoardResize как пустую директиву.

Lei Chi 04.06.2024 08:39
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
2
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Самый простой способ — просто передать экземпляр div в качестве параметра функции, для этого мы используем exportAs в директиве и указываем его в ссылочной переменной шаблона.

import { Component, Directive } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';

@Directive({
  selector: '[appBoardResize]',
  exportAs: 'appBoardResize',
  standalone: true,
})
export class AppBoardResize {
  innerProp = 'test';
}

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [AppBoardResize],
  template: `
  @for(item of items;track $index) {
    <div class = "item"
        #directive = "appBoardResize"
        (click) = "func($event, directive)"
        appBoardResize>
        some div
    </div>
    <div class = "item"
        #directive = "appBoardResize"
        (click) = "func($event, directive)"
        appBoardResize>
        some div 2
    </div>
  }
  `,
})
export class App {
  items = new Array(10);

  func(event: Event, directive: AppBoardResize) {
    console.info(event, directive);
  }
}

bootstrapApplication(App);

Демо-версия Stackblitz


Другой способ — использовать функцию angular viewChildren для получения всех директив в компоненте, массив будет доступен только на хуке ngAfterViewInit.

Поскольку вы используете angular 17, я рекомендую использовать сигналы, но то же самое можно сделать с помощью @ViewChildren(AppBoardResize) directives!: QueryList<AppBoardResize>;

import { Component, Directive, viewChildren } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';

@Directive({
  selector: '[appBoardResize]',
  standalone: true,
})
export class AppBoardResize {}

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [AppBoardResize],
  template: `
  @for(item of items;track $index) {
    <div class = "item"
        (click) = "func($event)"
        appBoardResize>
        some div
    </div>
    <div class = "item"
        (click) = "func($event)"
        appBoardResize>
        some div 2
    </div>
  }
  `,
})
export class App {
  directives = viewChildren(AppBoardResize);
  items = new Array(10);

  func(event: Event) {
    console.info(event);
  }

  ngAfterViewInit() {
    console.info(this.directives());
  }
}

bootstrapApplication(App);

Демо-версия Stackblitz

Спасибо, это отлично работает. Кстати, мне интересно, и я не могу не спросить, есть ли что-то вроде следующей логики, которую мы можем легко сделать? func($event) { //предположим, у нас есть getDirective или еще в angular? $event.element.nativeElement.getDirective(AppBoardResize); }

Lei Chi 04.06.2024 09:59

@LeiChi Это мои главные рекомендации, если вы хотите присвоить переменную свойству компонента и вместо этого использовать свойство внутри функции (click) = "tempVar = directive;func($event)"

Naren Murali 04.06.2024 10:01

Это хорошо, проголосовали за, и будет еще одна попытка.

Lei Chi 04.06.2024 10:05

Другие вопросы по теме