Как я могу закрыть раскрывающийся список на клик снаружи?

Я хотел бы закрыть раскрывающееся меню входа в систему, когда пользователь щелкнет в любом месте за пределами этого раскрывающегося списка, и я хотел бы сделать это с Angular2 и с «подходом» Angular2 ...

Я реализовал решение, но я действительно не уверен в этом. Я думаю, что должен быть самый простой способ достичь того же результата, так что если у вас есть идеи ... давайте обсудим :)!

Вот моя реализация:

Раскрывающийся компонент:

Это компонент для моего выпадающего списка:

Каждый раз, когда этот компонент становится видимым (например, когда пользователь нажимает на кнопку, чтобы отобразить его), он подписывается на «глобальную» тему rxjs.Меню пользователя хранится вSubjectsService.И каждый раз, когда он скрыт, он отписывается на эту тему.Каждый клик в любом местев шаблон этого компонента вызываетпо щелчку() метод, который просто останавливает всплеск событий наверх (и компонент приложения)

Вот код

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;
    }
}
Компонент приложения:

С другой стороны, есть компонент приложения (который является родителем выпадающего компонента):

Этот компонент перехватывает каждое событие щелчка и отправляет на тот же объект rxjs (Меню пользователя)

Вот код:

export class AppComponent {

    constructor( public subjects: SubjectsService) {
        document.addEventListener('click', () => this.onClick());
    }
    onClick( ) {
        this.subjects.userMenu.next({});
    }
}
Что меня беспокоит:Я не чувствую себя действительно комфортно с идеей иметь глобальный субъект, который действует как соединитель между этими компонентами.SetTimeout: Это необходимо, потому что вот что происходит иначе, если пользователь нажимает кнопку, отображающую выпадающий список:Пользователь нажимает кнопку (которая не является частью раскрывающегося компонента), чтобы отобразить раскрывающийся список.Раскрывающийся список отображается иэто сразу подписаться на тему userMenu.Событие click всплывает до компонента приложения и попадаетКомпонент приложения генерирует событие наМеню пользователя предметВыпадающий компонент ловит это действие наМеню пользователя и скрыть раскрывающийся списокВ конце выпадающий никогда не отображается.

Этот установленный тайм-аут задерживает подписку до конца текущего поворота кода JavaScript, что решает проблему, но, на мой взгляд, очень элегантно.

Если вы знаете, чище, лучше, умнее, быстрее или сильнее решения, пожалуйста, дайте мне знать :)!

Ответы на вопрос(18)

Ваш ответ на вопрос