2014-01-27 2 views
0

My keypress обработчик события всегда одно нажатие клавиши и как-то $timeout исправляет это.

<body ng-controller="myController"> 
    <form> 
    <input ng-keypress="handleKeypress($event)" /> 
    </form> 
</body> 

Контроллер:

myapp.controller('myController', function($scope, $timeout){  
    $scope.handleKeypress = function(ev){ 

     console.log(ev.target.value); //always one keystroke behind 

     //$timeout(function(){console.log(ev.target.value);}); //works!   
    }; 
}); 

Почему $timeout необходимо и почему/как это работает?

Я понимаю, что с событием keypress символ еще не был вставлен в DOM, но я смущен, потому что пример Hello World в angularjs.org отвечает перед тем, как ключ будет выпущен.

(Их пример не использует пользовательский обработчик событий, но явно Угловая обновляет модель перед keyup события, поэтому я хотел бы понять больше об этом в обработчике пользовательского события.)

event.which доступен на keypress и keydown, и я подумал, что, возможно, Angular может использовать String.fromCharCode(), но я не вижу ничего в этом угловом источнике.

+0

$ таймаут заставляет дайджеста случиться. Хотя ng-keypress также должен вызвать дайджест, поэтому я не уверен, почему это один удар позади. Есть ли больше кода, который вы не публикуете? –

+1

Я думаю, что это проблема с событием onkeypress, проверьте следующее: http://stackoverflow.com/questions/9349587/javascript-onkeypress-event-fires-but-input-text-value-is-incorrect, http: // stackoverflow .com/questions/5340751/javascript-last-character-missing-on-onkeypress-event –

ответ

2

$timeout позволяет выполнять свою функцию в следующем цикле после того, как значение добавлено в поле в конце текущего цикла. В основном, с $timeout, вы говорите ему подождать, и пока он ждет, ev.target.value обновляется.

Что касается примера. Угловой работает с грязными проверками, которые ищут вещи, которые изменяются в событиях пользовательского интерфейса, вот как он знает, чтобы обновить его значение. Это происходит после события нажатия клавиши. Грязные проверки основаны на тайм-аутах. Вы можете увидеть здесь: http://jsfiddle.net/TheSharpieOne/V6p9M/1/, что область $ не обновляется при запуске вашей функции. Измените журнал на предупреждение, и вы увидите, что DOM также не обновляется.

Если вы пытаетесь избежать этого звонка $timeout, вы можете использовать событие ngChange. В отличие от обычного onChange (который срабатывает на blur), ngChange будет стрелять каждый раз, когда значение будет изменено, например, нажатие клавиши.

http://jsfiddle.net/TheSharpieOne/V6p9M/

+0

У меня есть неопределенное понятие цикла событий браузера - это то, что подразумевается под «циклом»? – KnewB

+1

Да. Извините за разницу в терминологии. Для меня [на мой взгляд] цикл события - это процесс, а цикл - это один экземпляр/прогон цикла события. – TheSharpieOne

Смежные вопросы