首页 > 解决方案 > 当它用于同一指令的多个实例时,如何仅创建一个 HostListener 实例

问题描述

我有指示。

@Directive({
  selector: '[autoCompletion]',
  exportAs: 'autoCompletion'
})
export class AutoCompleteDirective {
 @HostListener('document:click', ['$event.target']) onDocumentClick(targetElement) {
    if (targetElement.id !== this.autoCompleteSearchInput) {
        this.p.closeDropDown();
    }
  }

}

每当在输入之外单击时,我都会在其中收听-下拉菜单应关闭。

问题是创建了乘法指令-

例如:

 <input autoCompletion/>
 <input autoCompletion/>
 <input autoCompletion/>
 <input autoCompletion/>
 <input autoCompletion/>

这意味着当我单击 HTML 文档时,会调用五次方法 - onDocumentClick。

我怎样才能防止这种情况发生?

我用谷歌搜索并没有找到解决方案

标签: angular

解决方案


您可以在指令之外控制文档 onclick

如果在您的组件中,您使用 viewChildren 获得 AutoCompleteDirective 并使用 fromEvent 进行控制

@ViewChildren(AutoCompleteDirective)autocompletes:QueryList<AutoCompleteDirective>

ngOnInit()
{
   formEvent(document,'click').subscribe(event=>{
       this.autocompletes.forEach(x=>{
         if (event.targetElement.id !== x.autoCompleteSearchInput) {
              x.p.closeDropDown();
         } 
       })
   })
}  

我想另一种选择是创建一个管理文档点击事件的新指令(但我不太确定)

@Directive({
 selector: 'formAutocompletion'
})
export class FormAutoCompletionDirective {
 click$ = fromEvent(document, 'click').pipe(shareReplay(1))
}

现在你的指令可以询问它

@Directive({
  selector: '[autoCompletion]',
  exportAs: 'autoCompletion'
})
export class AutoCompleteDirective {
  click$: Observable<Event>;

  constructor(@Optional() @Host() private form: FormAutoCompletionDirective)
  {
    this.click$ = this.form ? this.form.click$ : null
  }

  ngOnInit(){
    if (this.click$){
      this.click$.subscribe((event)=>{
        if (event.targetElement.id !== this.autoCompleteSearchInput) {
          this.p.closeDropDown();
      }
    }
  }

你写

<form formAutoComplete>
   <input autoCompletion/>
   <input autoCompletion/>
   ...
</form>

推荐阅读