简体   繁体   English

使用指令检测角度4中的Click外部元素

[英]Detect Click outside element in angular 4 using directives

I have used a custom directive to detect click outside an element in angular 2 but the same is not possible in angular 4. 我使用了一个自定义指令来检测角度2中某个元素的外部单击,但是在角度4中是不可能的。

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

When I try using the same code in angular-4 I get the following errors: 当我尝试在angular-4中使用相同的代码时,出现以下错误:

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();
}

If there is any change in the directive declaration in angular 4 please let me know, the official docs are of no help in this matter. 如果angular 4的指令声明有任何变化,请告诉我,官方文档在这方面没有帮助。

There are few changes in relation to your plnkr. 与plnkr的关系很少。

  1. NgModules , or rather take a look on Archietcture of the framework. NgModules ,或者更确切地说,采取一看Archietcture框架。 The module is the place where you should register your components, services and directices 该模块是您应该注册组件,服务和指令的地方
  2. Once you registered your directive inside module you don't have to import it inside components 在模块中注册指令后,您无需将其导入组件中

The directive itself looks fine for me. 该指令本身对我来说很好。 I compared your directive with mine that works fine in Angular 4.3.5. 我将您的指令与在Angular 4.3.5中可以正常工作的我的指令进行了比较。

Actually, you don't need any directive in that case, unless it won't be used repetitive. 实际上,在那种情况下,您不需要任何指令,除非不会重复使用它。 If you need to apply that clickOutside only for menu it would be better to do sth like that: 如果您仅需要将clickOutside应用于菜单,最好这样做:

Bind click event to your "inside" selector like that. 像这样将点击事件绑定到您的“内部”选择器。 Let's say it's your menu: 假设这是您的菜单:

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

then inside your component add clickedInside() function like this: 然后在组件内部添加clickedInside()函数,如下所示:

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

And finally you can use Host Listener in your component to bind click also to the rest of document 最后,您可以在组件中使用Host Listener来将click也绑定到文档的其余部分

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM