使用指令检测角度 4 中的单击外部元素 [英] Detect Click outside element in angular 4 using directives

查看:28
本文介绍了使用指令检测角度 4 中的单击外部元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用了一个自定义指令来检测 angular 2 中元素外部的点击,但在 angular 4 中是不可能的.

I have used a custom directive to detect click outside an element in angular 2 but the same is not possible in angular 4.

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

当我尝试在 angular-4 中使用相同的代码时,出现以下错误:

When I try using the same code in angular-4 I get the following errors:

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

如果 angular 4 中的指令声明有任何变化,请告诉我,官方文档在这方面没有帮助.

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.

推荐答案

与您的 plnkr 相关的变化很少.

There are few changes in relation to your plnkr.

  1. NgModules,或者看看 架构 框架.模块是您应该注册组件、服务和指令的地方
  2. 一旦你在模块中注册了你的指令,你就不必在组件中导入它
  1. NgModules, or rather take a look on Archietcture of the framework. 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

指令本身对我来说看起来不错.我将您的指令与在 Angular 4.3.5 中运行良好的指令进行了比较.

The directive itself looks fine for me. I compared your directive with mine that works fine in Angular 4.3.5.

实际上,在这种情况下您不需要任何指令,除非它不会被重复使用.如果您只需要将 clickOutside 应用于菜单,最好这样做:

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:

像这样将点击事件绑定到您的内部"选择器.假设这是您的菜单:

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>

然后在您的组件中添加 clickedInside() 函数,如下所示:

then inside your component add clickedInside() function like this:

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

最后,您可以在您的组件中使用 Host Listener 将点击也绑定到其余部分文档

And finally you can use Host Listener in your component to bind click also to the rest of document

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

这篇关于使用指令检测角度 4 中的单击外部元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆