Angular 2 событие изменения при каждом нажатии клавиши

282

Событие изменения вызывается только после изменения фокуса ввода. Как сделать так, чтобы событие срабатывало при каждом нажатии клавиши?

<input type="text" [(ngModel)]="mymodel" (change)="valuechange($event)" />
{{mymodel}}

Второе связывание меняется при каждом нажатии клавиши между прочим.

Даниил
источник

Ответы:

475

Я просто использовал ввод события, и он работал нормально следующим образом:

в .html файле:

<input type="text" class="form-control" (input)="onSearchChange($event.target.value)">

в файле .ts:

onSearchChange(searchValue: string): void {  
  console.log(searchValue);
}
Рами Фетеха
источник
Хороший. Работает для меня.
Годекере
это именно то, что я искал
Франческо Борци
как мы задерживаемся на некоторое время?
Махмуд Хбубати
Прекрасно работает! Спасибо
Веда Пери
Работает
Рахул Лад
193

Используйте ngModelChange, разбив [(x)]синтаксис на две части, то есть привязку данных свойства и привязку события:

<input type="text" [ngModel]="mymodel" (ngModelChange)="valuechange($event)" />
{{mymodel}}
valuechange(newValue) {
  mymodel = newValue;
  console.log(newValue)
}

Это работает и для клавиши возврата.

Марк Райкок
источник
5
Но при использовании банана в синтаксисе ящика это только меняет модель, но вы не можете что-то перехватить в событии изменения.
Гиора Гутцаит
4
Это отличный ответ для лучшего двустороннего связывания данных. Должен быть принятый ответ!
Tk1993
4
Клавиша
Каран
4
Это решение является правильным. Однако имейте в виду, что ngModelChange запускается ДО обновления значения. Таким образом, «newValue» в этом примере содержит модель БЕЗ только что нажатой клавиши - поэтому у вас нет обновленной модели там. Если вы хотите иметь самое последнее значение модели, используйте событие (keyup).
dave0688
1
@SateeshKumarAlli какая у вас версия Angular? Для меня это действительно обнаруживает возврат в Angular 6.1.3
Jette
96

Событие (keyup) - ваш лучший выбор.

Посмотрим почему:

  1. (изменить), как вы упомянули, срабатывает только тогда, когда вход теряет фокус, поэтому имеет ограниченное использование.
  2. (нажатие клавиши) срабатывает при нажатии клавиш, но не срабатывает при определенных нажатиях клавиш, например, при возврате.
  3. (keydown) срабатывает каждый раз, когда нажимается клавиша. Следовательно, всегда отстает на 1 символ; так как он получает состояние элемента до того, как было зарегистрировано нажатие клавиши.
  4. (keyup) - ваша лучшая ставка, так как она срабатывает каждый раз, когда завершается событие нажатия клавиши, поэтому сюда также входит самый последний символ.

Итак, (keyup) - самый безопасный вариант, потому что ...

  • регистрирует событие при каждом нажатии клавиши в отличие от (изменения) события
  • включает в себя ключи, которые (нажатие клавиши) игнорирует
  • не имеет задержки в отличие от события (keydown)
Сагар
источник
4
Как упоминалось в одном из ответов, входное событие работает очень хорошо. keyupЭто, безусловно, один из самых безопасных вариантов, однако, inputсобытие на шаг впереди keyup. keyupв отличие от input, не работает, если значение текстового поля изменяется любым другим способом, например, связывание.
planet_hunter
1
Сагар, большое спасибо. Это должен быть Принятый ответ, так как он единственный, который на самом деле адресован (change)наряду с обходным решением, а затем и некоторым. Принятый ответ - полный отстой!
Коди
Есть ли какая-то конкретная причина, по которой вы хотели бы сделать это снова (ngModelChange)?
SnailCoil
1
Это должен быть принятый и самый безопасный ответ, поскольку он является родным и дает вам полный контроль, и он очень выразителен, потому что каждый, кто его читает, точно знает, когда происходит событие.
Флориан Лейтгеб
1
@ThariqNugrohotomo Нет, не будет. Используйте (вход), если вы ищете что-то подобное.
Сагар
39
<input type="text" [ngModel]="mymodel" (keypress)="mymodel=$event.target.value"/>
{{mymodel}}
Гюнтер Цохбауэр
источник
10
работает, но странно, клавиша возврата не распознается как нажатие клавиши?
Даниэль
22
Вы можете использовать keydownили keyupвместо. Некоторые ключи просто не срабатывают keypress. См. Также stackoverflow.com/questions/4843472/…
Гюнтер Цохбауэр
Я пробовал события keydown, keyup и change, но когда ввод w, обработчик событий сообщает мне пустую строку; когда вводим мы, обработчик событий сообщает мне w как вход. Не могли бы вы объяснить, почему это поведение?
предусмотрительно
Используйте клавишу. Ввод еще не изменился при нажатии клавиш.
Гюнтер Цохбауэр
1
Это странно, но я получаю задержку ввода, когда значение не содержит набранного значения до следующего нажатия клавиши.
Мэтт Эланд
25

Другим способом обработки таких случаев является использование formControl и подписка на него valueChangesпри инициализации вашего компонента, что позволит вам использовать операторы rxjs для расширенных требований, таких как выполнение http-запросов, применение debounce до тех пор, пока пользователь не закончит писать предложение, принять последнее значение и пропустить предыдущее, ...

import {Component, OnInit} from '@angular/core';
import { FormControl } from '@angular/forms';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';

@Component({
  selector: 'some-selector',
  template: `
    <input type="text" [formControl]="searchControl" placeholder="search">
  `
})
export class SomeComponent implements OnInit {
  private searchControl: FormControl;
  private debounce: number = 400;

  ngOnInit() {
    this.searchControl = new FormControl('');
    this.searchControl.valueChanges
      .pipe(debounceTime(this.debounce), distinctUntilChanged())
      .subscribe(query => {
        console.log(query);
      });
  }
}
Салем Урдани
источник
2
Это потрясающе. Это подавляет болтовню при использовании этого для асинхронных HTTP-запросов. Также уже настраивает слушатели события изменения. Brilliant! Спасибо!
Хьюстон
Рад, что это помогло. Спасибо @hewstone
Салем Урдани
1
В случае нескольких элементов управления, тот же код может быть применен сFormGroup
Викаш Кумар
20

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

<input type="text" [(ngModel)]="mymodel" (input)="valuechange($event)" />
{{mymodel}}
Эмека Обианом
источник
Это делает для меня @AndreiDiaconescu
KhoPhi
Событие (input) не поддерживается в браузерах Edge и IE. Какая альтернатива этому в браузере Edge?
Sudhakar
6
<input type="text" (keypress)="myMethod(myInput.value)" #myInput />

архив .ts

myMethod(value:string){
...
...
}
Ulric Merguiço
источник
Добро пожаловать в SO Ulric, пожалуйста, объясните, как ваш код решает проблему.
CPHPython
4

То, что вы ищете, это

<input type="text" [(ngModel)]="mymodel" (keyup)="valuechange()" />
{{mymodel}}

Затем делайте с данными все, что хотите, this.mymodelоткрывая границы в вашем файле .ts.

Санкет Берде
источник
2

В моем случае решение состоит в следующем:

[ngModel]="X?.Y" (ngModelChange)="X.Y=$event"
хатем хтира
источник
1

Для Реактивных форм вы можете подписаться на изменения, внесенные во все поля или только в определенное поле.

Получить все изменения FormGroup:

this.orderForm.valueChanges.subscribe(value => {
    console.dir(value);
});

Получить изменение конкретного поля:

this.orderForm.get('orderPriority').valueChanges.subscribe(value => {
    console.log(value);
  });
stayingcool
источник
0

Я использовал keyup для числового поля, но сегодня я заметил, что в chrome на входе есть кнопки вверх / вниз для увеличения / уменьшения значения, которые не распознаются keyup.

Мое решение состоит в том, чтобы использовать keyup и изменить вместе:

(keyup)="unitsChanged[i] = true" (change)="unitsChanged[i] = true"

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

user9273992
источник