прослушивание щелчка по указанному c элементу в angular - PullRequest
1 голос
/ 12 марта 2020

У меня вопрос по поводу концепции angular. Я спрашиваю это с примером.

Например, у меня есть несколько ссылок, подобных этим пунктам в моем меню вне холста:

<ul class="my_ul">
    <li> <a (click)="do1()">do1</a> </li>
    <li> <a (click)="do2()">do2</a> </li>
    <li> <a (click)="do3()">do3</a> </li>
    ...
</ul>

Я хочу знать, когда пользователь нажимает ul.my_ul > li > a тогда я запускаю closeOffcanvas() функцию.

  • Я не хочу добавлять свой closeOffcanvas() в do1() или do2() или ...
  • Я надеваю не хочу создавать directive.
  • Я не хочу добавлять 2 функции, такие как: (click)="do1(); closeOffcanvas()"

Чтобы получить то, что я имею в виду: В jquery Я могу сделать это: (без каких-либо html изменений)

$('ul.my_ul > li > a').click(function(){
    //my close off-canvas codes
});

Как мне сделать подобное в Angular?

Я хочу прослушивать события указанного c списка элементов в компоненте без изменений HTML.

note: пожалуйста, не решайте проблему примера. это не моя проблема. это только пример для объяснения моего значения.

Ответы [ 4 ]

1 голос
/ 14 марта 2020

Итак, я суммирую окончательный и лучший ответ:

Сначала мы получаем доступ к элементам с помощью ElementRef, например:

const elements = this.elementRef.nativeElement.querySelectorAll("ul.class_name li > a");

, затем мы слушаем события элемента с помощью Renderer2, вот так:

elements.forEach( element => {
    this.renderer.listen(element, "click", event => {
        //do something...
    });
});

Не забудьте импортировать эти:

import { ElementRef, Renderer2 } from '@angular/core';

и:

constructor( private elementRef:ElementRef, private renderer:Renderer2 ){ }
1 голос
/ 12 марта 2020

Вы можете использовать HostListener, Renderer2 или вы можете задать элементу ul событие click.

Вот пример последнего решения:

https://stackblitz.com/edit/angular-gfnohf?file=src%2Fapp%2Fapp.component.ts


С помощью события вы можете увидеть, какой элемент был нажал

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

  do1() {
    console.log('do1');
  }
  do2() {
    console.log('do2');
  }
  do3() {
    console.log('do3');
  }  

  closeOffcanvas(event) {
    if(event.target.matches('a'))
    {
      console.log('user clicked on: ', event.target, 'with name: ', event.target.innerHTML);
    }    
  }
}
<ul class="my_ul" (click)="closeOffcanvas($event)">
    <li> <a (click)="do1()">do1</a> </li>
    <li> <a (click)="do2()">do2</a> </li>
    <li> <a (click)="do3()">do3</a> </li>
</ul>

обновить пример без изменения html

Лучше не связывать событие для всех элементов списка. Производительность намного выше, если вы только связываете элемент-обертку и проверяете, является ли event.target правильным дочерним элементом

https://stackblitz.com/edit/angular-oqjstq?file=src%2Fapp%2Fapp.component.ts


1 голос
/ 12 марта 2020

Кажется, вы можете использовать ElementRef для выбора элементов в текущем компоненте, например:

@Component({
  selector: "my-app",
  template: `
    <ul>
      <li><a (click)="do1()">do1</a></li>
      <li><a (click)="do2()">do2</a></li>
    </ul>
  `
})
export class AppComponent implements OnInit, OnDestroy {

  constructor(private elementRef: ElementRef) {}

  ngOnInit() {
    const elements = this.elementRef.nativeElement.querySelectorAll("ul > li > a");
    elements.forEach(element => {
      element.addEventListener("click", this.doCommon);
    });
  }

  ngOnDestroy() {
    const elements = this.elementRef.nativeElement.querySelectorAll("ul > li > a");
    elements.forEach(element => {
      element.removeEventListener("click", this.doCommon);
    });
  }

  do1() { console.log("do1"); }
  do2() { console.log("do2"); }
  doCommon() { console.log("common"); }

}

Если вы не хотите ограничивать свой запрос содержимым текущего компонента, вы может заменить this.elementRef.nativeElement на document.

Я не использовал его в прошлом, но он отлично работает в моем проекте StackBlitz .

Может быть, в целом ngOnDestroy() для предотвращения утечек памяти нет необходимости в современных браузерах, но я все еще чувствую себя немного безопаснее, делая это:)

0 голосов
/ 12 марта 2020

Просто получите родительскую ссылку, обработайте родительский объект как коллекцию, переберите его и назначьте прослушиватели событий. (В синтаксисе Angular вы можете использовать HostListener ).

Пример: https://stackblitz.com/edit/angular-6fsjhu?file=src%2Fapp%2Fapp.component.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...