代码之家  ›  专栏  ›  技术社区  ›  Phaze

处理多个组件的角度单击事件

  •  1
  • Phaze  · 技术社区  · 7 年前

    这个问题快把我逼疯了。我有两个组件,都是在同一页上可切换的下拉列表。我对这两个组件都有类似的功能:

    @HostListener('click', ['$event'])
    clickInside() {
      event.stopPropagation();
      this.showMenu = true;
    }
    
    @HostListener('document:click')
    clickOutside() {
      if (this.showMenu) {
        this.showMenu = false;
      }
    }
    

    它只适用于一个组件,但当我在同一页上有两个组件时,单击另一个组件将使第一个组件保持打开状态,结果是它们同时打开,这是我不希望看到的。原因当然是 事件.停止播放() 但如果不这样做,组件内部的单击也将是文档内部的单击。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Buggy    7 年前

    当我们在组件内部单击时,它应该被打开,当单击在外部时,它应该被关闭。

      constructor(private elementRef: ElementRef){}
    
      @HostListener('click')
      clickInside() {
        this.showMenu = true;
      }
    
      @HostListener('document:click', ['$event'])
      clickOutside(event) {
        if (this.showMenu && this.isClickOutside(event)) {
          this.showMenu = false;
        }
      }
    
      private isClickOutside(event: MouseEvent): boolean {
        return !this.elementRef.nativeElement.contains(event.target);
      }
    

    private readonly onDestroy$ = new Subject();
    
    constructor( private ngZone: NgZone,) {}
    
    ngOnInit() {
        this.ngZone.runOutsideAngular(() => {
          fromEvent(window.document, 'click')
            .pipe(
              filter(
                (event: MouseEvent) =>
                  this.isOpen() && this.isClickOutside(event)
              ),
              takeUntil(this.onDestroy$),
            )
            .subscribe(() => {
              this.ngZone.run(() => {
                this.close();
              });
            });
        });
      }
    
    ngOnDestroy() {
        this.onDestroy$.next();
        this.onDestroy$.complete();
      }
    
    推荐文章