I am trying to listen to a directive event on an element. Renderer.listen is not picking up the event.

HTML code:

<a click-elsewhere #assignmentOptions>
    <pp-click-dropdown [clickElement]="assignmentOptions">
        <a>Test Button</a>
    </pp-click-dropdown>
</a>

pp-click-dropdown.ts - clickElsewhere() is the directive event in the 'click-elsewhere' directive. This is event is emitting properly. I am not getting any errors, Renderer.listen is just not picking up the directive event.

import { Component, EventEmitter, Input, Output, Renderer, OnInit } from '@angular/core';

@Component({
    selector: 'pp-click-dropdown',
    templateUrl: 'panelply-click-dropdown.component.html',
})

export class PanelPlyClickDropdownComponent implements OnInit {
    @Input() clickElement: Element;
    @Output() onDropdownClick: EventEmitter<any> = new EventEmitter();

    private renderer: Renderer;

    constructor(_renderer: Renderer) {
        this.renderer = _renderer;
    }

    ngOnInit() {
        this.renderer.listen(this.clickElement, 'click', (event) => {
            this.toggleDropDown(event);
        }); // this line is working properly
        this.renderer.listen(this.clickElement, 'clickElsewhere', (event) => {
            console.log('clicked oustide')
            this.closeDropdown(event);
        }); // this line is not working
    }

    toggleDropDown(e) {
        this.isShown = !this.isShown;
        this.onDropdownClick.emit(e);
    }

    closeDropdown(event: Object) {
        if (event && event['value'] === true) {
            this.isShown = false;
        }
    }
}

click-elsewhere.ts (directive)

import { Directive, ElementRef, EventEmitter, OnDestroy, OnInit, Output, HostListener } from '@angular/core';
import { Subscription } from 'rxjs';

@Directive({
    selector: '[click-elsewhere]'
})

export class ClickElsewhereDirective implements OnInit, OnDestroy {
    @Output() clickElsewhere: EventEmitter<Object>;

    constructor(private _elRef: ElementRef) {
        this.clickElsewhere = new EventEmitter();
    }

    @HostListener('document:click', ['$event.target'])
    public onClick(targetElement) {
        const clickedInside = this._elRef.nativeElement.contains(targetElement);
        if (!clickedInside) {
            console.log('clicked outside source')
            this.clickElsewhere.emit(null);
        }
    }
}

Is there something I'm missing here? Does listen not work because directive events are not DOM events? Is there a way to do this?

1 Answers

0
user2777664 On

This isn't really the way I wanted to do this because I want 'click-elsewhere' and 'pp-click-dropdown' to modular and I didn't want to potential run into issues later on different elements, but it works:

<a click-elsewhere (clickElsewhere)="dropdown.isShown = false;" #assignmentOptions>
    <pp-click-dropdown #dropdown [clickElement]="assignmentOptions">
        <a>Test Button</a>
    </pp-click-dropdown>
</a>