web-dev-qa-db-fra.com

Détecter Cliquez à l'extérieur de l'élément dans angular 4 en utilisant des directives

J'ai utilisé une directive personnalisée pour détecter le clic en dehors d'un élément dans angular 2 mais la même chose n'est pas possible dans angular 4.

[plunkr]https://plnkr.co/edit/aKcZVQ?p=info

Lorsque j'essaie d'utiliser le même code dans angular-4, j'obtiens les erreurs suivantes:

1. Argument of type '{ template: string; directives: typeof ClickOutside[]; }' is not assignable to parameter of type 'Component'. ==> 

    @Component({
    templateUrl: "",
    directives: [ClickOutside]
    })


2. Type 'Subscription' is not assignable to type 'Observable<MouseEvent>'. in the directive inside ngOnInit() and ngOnDestroy() 

ngOnInit() {
    this.globalClick = Observable
        .fromEvent(document, 'click')
        .delay(1)
        .do(() => {
            this.listening = true;
         }).subscribe((event:MouseEvent) => {
            this.onGlobalClick(event);
         });
}

ngOnDestroy() {
    this.globalClick.unsubscribe();
}

S'il y a un changement dans la déclaration de directive dans angular 4 s'il vous plaît laissez-moi savoir, les documents officiels ne sont d'aucune aide dans cette affaire.

20
Ronit Oommen

Il y a peu de changements par rapport à votre commande.

  1. NgModules , ou plutôt jetez un oeil sur Archietcture du framework. Le module est l’endroit où vous devez enregistrer vos composants, services et directices
  2. Une fois que vous avez enregistré votre directive dans le module, vous n'avez plus besoin de l'importer dans les composants.

La directive elle-même me semble bien. J'ai comparé votre directive avec la mienne qui marche bien dans Angular 4.3.5.

En fait, dans ce cas, vous n’avez pas besoin de directive, à moins qu’elle ne soit pas répétitive. Si vous avez besoin d’appliquer ce clickOutside uniquement pour le menu, il serait préférable de le faire comme ça:

Liez click event à votre sélecteur "inside" comme ça. Disons que c'est votre menu:

  <ul id="menu" (click)="clickedInside($event)"> <li> .. </li> </ul>

ensuite, dans votre composant, ajoutez clickedInside() comme ceci:

  clickedInside($event: Event){
    $event.preventDefault();
    $event.stopPropagation();  // <- that will stop propagation on lower layers
    console.log("CLICKED INSIDE, MENU WON'T HIDE");
  }

Et enfin, vous pouvez utiliser Host Listener dans votre composant pour lier un clic au reste du document.

  @HostListener('document:click', ['$event']) clickedOutside($event){
    // here you can hide your menu
    console.log("CLICKED OUTSIDE");
  }
50
Kuba