Angular 2 - 绑定和解除绑定HostListener事件

时间:2017-01-10 00:45:06

标签: javascript angular javascript-events

我正在尝试根据组件的输入变量绑定和取消绑定HostListener单击事件。

该组件是一个弹出窗口,其中包含一个名为show的输入。此输入保持弹出窗口的活动/非活动状态。我想在整个文档上触发click事件,但仅当输入show设置为true时才会触发。

有没有办法在我有的ngOnChanges函数中绑定和取消绑定hostlistener事件?

我目前的代码:

import {Component, OnInit, Input, ViewEncapsulation, HostListener} from '@angular/core';

@Component({
    selector: 'custom-popup',
    templateUrl: './popup.component.html',
    styleUrls: ['./popup.component.scss'],
    encapsulation: ViewEncapsulation.None
})
export class PopupComponent implements OnInit {

    @Input() show: boolean = false;

    constructor() {
    }

    ngOnInit() {
    }


    @HostListener('document:click', ['$event.target'])
    clickHandler(targetElement) {
        // Custom code to handle click event
    }

    ngOnChanges(show: boolean) {
        if (this.show) {
            // Bind Click Event
        }
        else {
            // Unbind Click Event
        }
    }
}

非常感谢任何帮助和见解。

2 个答案:

答案 0 :(得分:1)

要确保在显示弹出窗口时只设置一个主机侦听器,请引入一个新的子组件PopupBody,其中包含主机侦听器,并@Output()将事件传递回来到Popup组件。

然后,在您的模板中,使用PopupBody使*ngIf="show"组件成为条件,然后它应该只在显示弹出窗口时绑定主机侦听器,并在弹出窗口被隐藏时取消绑定。

答案 1 :(得分:-1)

最后,我使用服务实现了一个解决方案。该服务处理文档上的单击事件,并使用observable使组件能够订阅事件。

弹出组件在打开时订阅stateService点击observable,并在关闭时取消订阅。

弹出组件:

import {Component, OnInit, Input, ViewEncapsulation, HostListener} from '@angular/core';
import {StateService} from "../services/state.service";
import {Subscription} from "rxjs";  

@Component({
    selector: 'custom-popup',
    templateUrl: './popup.component.html',
    styleUrls: ['./popup.component.scss'],
    encapsulation: ViewEncapsulation.None
})
export class PopupComponent implements OnInit {

    @Input() show: boolean = false;

    constructor(private stateService: StateService) {
    }

    ngOnInit() {
    }

    ngOnChanges(show: boolean) {

        if (this.show) {

            // Timeout to ensure subscription after initial click
            setTimeout(() => {

                // Subscribe to the document click service when the input opens
                if (!this.clickSubscription || this.clickSubscription.closed) {
                    this.clickSubscription = this.stateService.documentClick$.subscribe(targetElement => {
                        // Logic for closing the popup
                    });
                }
            });
        }
        else {

            // Remove the subscription when the input closes
            if (this.clickSubscription && !this.clickSubscription.closed) {
                this.clickSubscription.unsubscribe();
            }
        }
    }
}

@GregL感谢您的建议