当用户点击下拉菜单之外的任何地方时,我想关闭我的登录菜单下拉菜单,我想用Angular2和Angular2"方法"来实现这一点...

我已经实施了一个解决方案,但我真的对它没有信心.我认为一定有一个最简单的方法来达到同样的效果,所以如果你有任何 idea ...让我们来讨论:)!

以下是我的实现:

The dropdown component:

这是我下拉列表的组件:

  • 每当该组件被设置为可见时(例如,当用户点击按钮以显示它时),它订阅存储在SubjectsService内的"全局"RXJS主题userMenu.
  • 每次它被隐藏,它就会取消订阅这个主题.
  • 该组件模板的每一次点击都会触发onClick()方法,它只会阻止事件冒泡到顶部(以及应用程序组件)

这是代码

export class UserMenuComponent {

    _isVisible: boolean = false;
    _subscriptions: Subscription<any> = null;

    constructor(public subjects: SubjectsService) {
    }

    onClick(event) {
        event.stopPropagation();
    }

    set isVisible(v) {
        if( v ){
            setTimeout( () => {
this._subscriptions =  this.subjects.userMenu.subscribe((e) => {
                       this.isVisible = false;
                       })
            }, 0);
        } else {
            this._subscriptions.unsubscribe();
        }
        this._isVisible = v;
    }

    get isVisible() {
        return this._isVisible;
    }
}

The application component:

另一方面,还有应用程序组件(下拉组件的父组件):

  • 该组件捕捉每个点击事件,并在同一个rxjs主题上发出(userMenu)

这是代码:

export class AppComponent {

    constructor( public subjects: SubjectsService) {
        document.addEventListener('click', () => this.onClick());
    }
    onClick( ) {
        this.subjects.userMenu.next({});
    }
}

What bother me:

  1. 我对把一个全球性的主题作为这些组成部分之间的连接点的 idea 感到不太舒服.
  2. setTimeout:这是必需的,因为如果用户单击显示下拉菜单的按钮,则会发生以下情况:
    • 用户单击该按钮(它不是DropDown组件的一部分)以显示下拉列表.
    • 显示下拉菜单和it immediately subscribe to the userMenu subject.
    • 点击事件泡沫一直到APP组件并被捕获
    • 应用程序组件在userMenu主题上发出事件
    • DropDown组件在userMenu上捕获此操作并隐藏该下拉菜单.
    • 最后从不显示下拉列表.

这将超时延迟订阅到当前JavaScript代码的末尾,解决了这个问题,但在我看来,这是一种非常优雅的方式.

如果你知道更干净、更好、更聪明、更快或更强的解决方案,请告诉我:)!

推荐答案

您可以使用(document:click)事件:

@Component({
  host: {
    '(document:click)': 'onClick($event)',
  },
})
class SomeComponent() {
  constructor(private _eref: ElementRef) { }

  onClick(event) {
   if (!this._eref.nativeElement.contains(event.target)) // or some similar check
     doSomething();
  }
}

另一种方法是创建自定义事件作为指令.查看本·纳德尔的以下帖子:

Angular相关问答推荐

Angular部署到IIS手动URL后不起作用

他们如何删除Clarity中的Angular组件包装器元素

如何go 除融合图中的拖尾水印?

尾风手风琴中的Ngor

Angular 服务错误处理响应类型=BLOB

访问Angular 模板中的HTML元素属性

首期日历发行

如何在ANGLING v17中使用鞋带样式组件?

独立组件;依赖项注入

有Angular react 形式的输入用货币管

筛选器不会从文本输入触发更改事件

确保我的角库S服务构建提供独立的友好提供功能

属性';apiUrl';在我的Angular 应用程序上不存在类型';{}';错误

如何在 Angular14 中创建带有验证的自定义输入组件?

Angular 在关闭另一个对话框后打开另一个对话框的最佳做法是什么?

Angular 2:Validators.pattern() 不工作

如何在angular 5的组件中格式化日期

Angular 2 Material Design 组件是否支持布局指令?

Angular 4 错误:没有 HttpClient 的provider提供者

angular2 测试,我如何模拟子组件