directive click outside angular 6

前端 未结 4 2185
广开言路
广开言路 2021-02-19 04:01

I upgraded my Angular from 4 to 6, and consequently had a problem with my click-off policy, it stopped working on all components.

my directive:



        
相关标签:
4条回答
  • 2021-02-19 04:13

    view:

    <div #insideElement></div>
    

    component:

    export class SomeClass {
      @ViewChild("insideElement") insideElement;
      @HostListener('document:click', ['$event.target'])
    
      public onClick(targetElement) {
        const clickedInside = this.insideElement.nativeElement.contains(targetElement);
        if (!clickedInside) {
          console.log('outside clicked');
        }
      }
    }
    
    0 讨论(0)
  • 2021-02-19 04:13

    This is a modification of @YoungHyeong Ryu answer above, but with unsubscription, so that the handler stops working when the component is unmounted.

    DEMO https://stackblitz.com/edit/angular-1q4pga

    import { Component, Input, OnInit, OnDestroy, ViewChild } from '@angular/core';
    
    @Component({
      selector: 'app-click-outside',
      template: `<div #insideElement>Click outside me.</div>`
    })
    export class ClickOutsideComponent implements OnInit, OnDestroy  {
      @ViewChild('insideElement', { static: false }) insideElement;
    
      public ngOnInit() {
        this.onDocumentClick = this.onDocumentClick.bind(this);
        document.addEventListener('click', this.onDocumentClick);
      }
    
      public ngOnDestroy() {
        document.removeEventListener('click', this.onDocumentClick);
      }
    
      protected onDocumentClick(event: MouseEvent) {
        if (this.insideElement.nativeElement.contains(event.target)) {
          return;
        }
        console.log('Clicked outside!');
      }
    }
    

    Here, we remove the event listener on destroy. Also, normally a method added by addEventListener is executed in a global context (instead of this context); so we should take care of it and bind onDocumentClick method to this (we do it in ngOnInit). Now we can use this inside onDocumentClick.

    0 讨论(0)
  • 2021-02-19 04:16

    Run the inside NgZone.

    Example:

    export class AppComponent {
      opened: boolean = false;
    
      constructor(private ngZone: NgZone) {
      }
    
      closeOutsideSidenav(e) {
        this.ngZone.run(() => {
          this.opened = !this.opened;
        })
      }
    }
    

    I added my code to stackblitz. https://stackblitz.com/edit/angular-gyhtym (click outside of the "Highlight Me!")

    0 讨论(0)
  • 2021-02-19 04:31

    You're referencing "this" in your template, which is not necessary. I made a working example of that directive:

    https://stackblitz.com/edit/angular-piqewb

    And theres no reason to have the directive on the div twice.

    <div id="sidenav" *ngIf="opened" class="sidenav" [ngClass]="getClasses()" [ngStyle]="getStyles()" (clickOutside)="closeOutsideSidenav()">
        <header> {{ navTitle }} </header>
        <i *ngIf="showCloseButton" class="iconic iconic-x-thin close-icon" (click)="closeSidenav()"></i>
        <ng-content></ng-content>
    </div>
    
    <div *ngIf="backdrop && opened" class="sidenav-backdrop"></div>
    
    0 讨论(0)
提交回复
热议问题