Могу ли я использовать несколько @hostlistener или событий на основе браузера?

#angular #events

#angular #Мероприятия

Вопрос:

Я использую @hostlistener в директиве Angular7. Могу ли я использовать для этого более одного события?

Проблема в том, что прослушивание события ‘keydown’ подходит для чего угодно, кроме Android, поскольку у последнего нет ключевых событий.

Переключение на событие ‘input’ решает эту проблему, но не распространяется на Firefox (и, вероятно, Edge), поскольку в последнем нет ‘inputType’ (и других вещей), что приводит к тому, что фактическое поле ввода разрешает любой ввод.

Итак, моя цель — иметь возможность использовать ‘keydown’ для Firefox и Edge и использовать ‘input’ для чего-либо еще. Возможно ли это?

Используемые события ‘keydown’, ‘keypress’ и ‘input’

     @HostListener('input', ['$event'])
    onInput(event: any) {
        this.parseKeyDown(event);
    }
  
     parseKeyDown(event: any) {
        if (event.inputType === 'deleteContentBackward' || event.inputType === 'deleteContentForward') {
            let str = this.ngModel.substr(0, this.ngModel.length - 1);
            if (str.length === 0) {
                str = '0';
            }
            // handle 'str'
        }
...
        if (e.inputType === 'insertText' amp;amp; e.data.match(this.regex)) {
            // handle ngModel
        }
    }
  

Код сокращен для удобства чтения.

Это работает во всем, кроме Firefox / Edge, где нажатие клавиш backspace или delete удаляет последний символ. В Firefox поле просто возвращается к текстовому полю, допускает любой ввод GUI и не обновляет ngModel.

Поскольку в Firefox нет ‘inputType’, ничего не происходит.


ОТРЕДАКТИРУЙТЕ мое решение

     @HostListener('keydown', ['$event'])
    @HostListener('input', ['$event'])
    onInput(e: any) {
        this.parseKeyDown(e);
    }

    parseKeyDown(e: any) {
        const key = e.key;
        if (key) { // Browsers WITH key events
...
        } else { // Browsers WITHOUT key events
            const data = e.data;
            const inputType = e.inputType;
...
  

Комментарии:

1. Вы могли бы использовать событие change

2. Спасибо, но событие «изменение» срабатывает только при удалении. Мне нужно обрабатывать каждый отдельный ввод по мере его возникновения

3. Если я вас правильно понял, вы хотите реализовать что-то вроде пользовательского элемента ввода с соответствующими обработчиками и графическим интерфейсом (возможно) и должны прослушивать изменения. Если я прав, вам следует посмотреть на элементы управления пользовательской формой, где вы можете управлять изменениями значений, change распространением и т. Д.

Ответ №1:

С @hostlistener помощью вы можете прослушивать одно событие с помощью одного декоратора. Если вы хотите прослушать несколько событий, вы можете добавить несколько @hostlistener к одной функции, например

 @HostListener('click', ['$event'])
@HostListener('mouseover', ['$event'])
onEvent(event) {
    console.log(event)
}
  

Если это нежелательно, вы можете подключиться к плагину Angular Event Manager и настроить его. Вот статья, показывающая это.

Комментарии:

1. Благодаря alt255 «двойной» hostlistener был тем, что мне было нужно. Оказывается, вы не можете решить, какой hostlistener использовать, поскольку только первый запущенный hostlistener переходит к методу. Поэтому, когда я использую « @HostListener(‘keydown’, [‘$event’]) @HostListener(‘input’, [‘$event’]) onInput(e: any) { this.parseKeyDown(e); } « и есть событие ‘keydown’, событие ‘input’ никогда не срабатывает.

2. @JohanFaerch Я сталкиваюсь с той же проблемой. вы нашли какое-либо решение или какую-либо альтернативу для этого

3. @pankajmalik Я добавил свое решение к первоначальному вопросу.

4. Если у вас обычно есть общая функция, но вам нужно провести определенные различия внутри: switch(event.type) {...