nativeElement.querySelector 在 Angular 中不起作用

nativeElement.querySelector not working in Angular

提问人:designArg 提问时间:7/13/2023 更新时间:7/13/2023 访问量:266

问:

我创建了一个list.directive.ts来封装一些功能并将其复制到多个组件中。我想在component.ts中使用该指令。

我试图在 html 中没有点击事件的情况下捕获按钮元素中的点击,这就是我使用@HostListener的原因,但是:

const specificElement = this.elementRef.nativeElement.querySelector('#button');似乎不起作用

法典

list.directive.ts

import {Directive, ElementRef, HostListener} from '@angular/core';
@Directive({
    selector: '[ListDirective]'
})
export class ListDirective{
    constructor(private elementRef: ElementRef) { }

    @HostListener('document:click', ['$event.target'])
    onClick(targetElement: HTMLButtonElement) {
       const specificElement = this.elementRef.nativeElement.querySelector('#button');
  
       if (targetElement === specificElement) {
         console.log('Specific element clicked');
       }
       
    }

}

list.module.ts

import { NgModule } from '@angular/core';
import { ListDirective } from './list.directive';
export { ListDirective };

@NgModule({
    declarations: [
        ListDirective
    ],
    exports: [
        ListDirective
    ]
})
export class ListModule {}

Main.ts

import {ListModule} from './app/list/list.module';

@NgModule({
  imports: [
    ListModule
  ],
  entryComponents: [TableBasicExample],
  declarations: [ListComponent],
  bootstrap: [TableBasicExample],
  providers: []
})
export class AppModule {}

我想使用 list 指令的组件:

component.ts

<ul>
  <li>
    <button id="button" ListDirective type="button"> Open</button>
    <ul>
        <li>Sublist</li>
    </ul>
  </li>
</ul>
Angular TypeScript 指令

评论

0赞 Aluan Haddad 7/13/2023
stackblitz.com/edit/angular-bklajw-3nwnv8。在查询之前,您需要提升一个级别
0赞 Eliseo 7/13/2023
如果只想“听”按钮你可以使用,看不听“document.click”否则“click”@HostListener('click',['$event.target', '$event']) onClick(targetElement: HTMLButtonElement, e: Event) {...} }

答:

0赞 Naren Murali 7/13/2023 #1

只需检查指定类的 classList,而不是比较元素,当按钮 id 位于指令所在的根元素时,您也在检查子元素。#button

import { Directive, ElementRef, HostListener } from '@angular/core';
@Directive({
  selector: '[ListDirective]',
})
export class ListDirective {
  constructor(private elementRef: ElementRef) {}

  @HostListener('document:click', ['$event.target', '$event'])
  onClick(targetElement: HTMLButtonElement, e: Event) {
    e.preventDefault();
    console.log(
      this.elementRef,
      targetElement,
      targetElement.classList.contains('click-happens-here')
    );
    const specificElement =
      this.elementRef.nativeElement.querySelector('#button');

    if (targetElement === specificElement) {
      console.log('Specific element clicked');
    }
  }
}

[html]

<ul>
  <li>
    <button id="button" class="click-happens-here" ListDirective type="button">
      Open
    </button>
    <ul>
      <li>Sublist</li>
    </ul>
  </li>
</ul>

堆栈闪电战

0赞 Eliseo 7/13/2023 #2

如果只想“听”,可以使用的按钮

 //, see that not listen the "document.click" else "click"
 @HostListener('click',['$event.target', '$event'])  
       onClick(targetElement: HTMLButtonElement, e: Event) {...}  
 }

如果你想听任何点击,你可以使用一些喜欢

@HostListener('click',['$event.target', '$event']) 
  onClick(targetElement: HTMLButtonElement, e: Event) {
    console.log(targetElement.tagName,targetElement.innerHTML)
    switch(targetElement.tagName)
    {
       case 'BUTTON':
           ...
       case 'LI':
           ...
    }
  }

并将该指令应用于 ul 或 li

<li ListDirective>
   ...
</li>

注意:除了 HostListener,您还可以使用 rxjs fromEvent 运算符

import { fromEvent, Subscription } from 'rxjs';
@Directive({
  selector: '[ListDirective]',
})
export class ListDirective implements OnInit, OnDestroy {
  subscription: Subscription;
  constructor(private elementRef: ElementRef) {}
  ngOnInit() {
    this.subscription = fromEvent(
      this.elementRef.nativeElement,
      'click'
    ).subscribe((_) => {
      console.log('click');
    });
  }
  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}