【问题标题】:Angular detect Click on any of the Links inside a component角度检测单击组件内的任何链接
【发布时间】:2021-07-02 04:19:00
【问题描述】:

我有一个自定义的side-nav 组件。

哪个可以用这个链接:

<button (click)="sideNav.open()">Menu</button>

<side-nav #sideNav>
    <a routerLinkActive="active" routerLink="/">Home</a>
    <a routerLinkActive="active" routerLink="/products">Products</a>
    <a routerLinkActive="active" routerLink="/about">About</a>
    <a routerLinkActive="active" routerLink="/contact">Contact</a>
</side-nav>

单击“菜单”按钮会打开带有 side-nav 标记内内容的侧导航。

我想在用户点击任何链接时自动关闭侧导航。

任何人都可以指导如何为我的 SideNavComponent 中的所有链接(和按钮)添加点击处理程序,以自动关闭“side-nav”

下面是我的组件:

import { Location } from "@angular/common";
import { Component, Input, Renderer2 } from '@angular/core';

@Component({
  selector: 'side-nav',
  templateUrl: './side-nav.component.html'
})
export class SideNavComponent {

  @Input() isOpen: boolean = false;
  @Input() enabled: boolean = true;
  @Input() extraClasses: string = '';
  
  constructor(private location: Location,
    private renderer: Renderer2) {
  }

  ngOnInit() {
  }

  open() {
    this.isOpen = true;
    window.addEventListener('popstate', this.onHardwareBackButton, { passive: true });
    this.location.go('side-nav');
    this.renderer.addClass(document.body, 'noscroll');
  }

  close(goBack: boolean = false) {
    this.isOpen = false;
    window.removeEventListener('popstate', this.onHardwareBackButton);
    this.renderer.removeClass(document.body, 'noscroll');
    if (goBack) {
      window.history.back();
    }
  }

  onHardwareBackButton = () => {
    this.close();
    window.removeEventListener('popstate', this.onHardwareBackButton);
  };
}

模板

<ng-container *ngIf="enabled">
  <nav id="sidebar-nav" [swipe]="true" (swipeLeft)="close(true)" [ngClass]="{'close':!isOpen,'open':isOpen}" class="{{extraClasses}}">
    <ng-container *ngTemplateOutlet="contentTpl"></ng-container>
  </nav>
  <div id="nav-screen-overlay" (click)="close(true)"></div>
</ng-container>

<ng-container *ngIf="!enabled">
  <ng-container *ngTemplateOutlet="contentTpl"></ng-container>
</ng-container>

<ng-template #contentTpl><ng-content></ng-content></ng-template>

我知道我可以在所有链接上添加(click)="sideNav.close()",但我想在用户点击任何可点击项目时自动添加,例如链接或按钮。

【问题讨论】:

  • 尝试在您的side-nav 中添加(click)="sideNav.close()"
  • 我希望它仅在用户点击任何可点击项目时关闭,例如链接或按钮
  • 在点击事件中,有一个target属性,在这里可以看到点击的元素是什么。所以你可以检查它是否是一个 a 标签,或者它是否有一个特定的 CSS 类?这会是一个解决方案吗?
  • 但是我如何在side-nav 中获取a click 事件,访问元素的一种方法是ViewChild,但这不允许按标签名称进行选择。

标签: angular angular-components


【解决方案1】:

你可以试试这个,但我想知道为什么你不能简单地在html 本身中添加click 事件,如果重复是你的问题,那么创建一个链接数组并循环(ngFor)它。

allListeners: (() => void)[] = [];
constructor(private elementRef: ElementRef, private renderer: Renderer2) {}

ngAfterViewInit() {
    const myComponent = this.elementRef.nativeElement as HTMLElement;
    const clickableElements = myComponent.querySelectorAll("a, button");
    clickableElements.forEach(eachElem => {
      const listener = this.renderer.listen(eachElem, "click", () => {
        console.log("Element clicked"); //Close sidenav
      });
      this.allListeners.push(listener);
    });
}

ngOnDestroy() {
    //Remove click listeners
    this.allListeners.forEach(listener => listener())
}

【讨论】:

  • 感谢分享这个 Sameer,实际上我想将此功能内置到我的 side-nav 组件中。与在html 中添加click 事件相比,这种方法有什么缺点吗?顺便说一句,我们应该使用 window.removeEventListener 来删除列表器吗?
  • @NaveedAhmed 我建议你阅读thiswatch this
猜你喜欢
  • 1970-01-01
  • 2012-12-18
  • 1970-01-01
  • 2012-11-27
  • 2011-05-23
  • 2016-08-19
  • 1970-01-01
  • 1970-01-01
  • 2018-03-06
相关资源
最近更新 更多