2014-01-27 183 views
0

我的按鍵事件處理程序始終是一個按鍵,並以某種方式$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中,但我很困惑,因爲angularjs.org上的Hello World示例在釋放一個密鑰之前做出響應。

(他們的榜樣不使用自定義事件處理程序,但顯然角被更新keyup事件之前的模型,所以我想了解更多關於自定義事件處理程序做這個。)

event.which可以在keypress和​​上找到,我想也許Angular可能會使用String.fromCharCode(),但是我沒有看到Angular的源代碼中有這個效果。

+0

$ timeout強制摘要發生。雖然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得到更新。

就這個例子而言。 Angular正在運行髒檢查來查找UI事件發生變化的事情,這就是它知道如何更新其值。它發生在按鍵事件之後。髒檢查是基於超時的。你可以在這裏看到:http://jsfiddle.net/TheSharpieOne/V6p9M/1/當你的函數運行時$ scope不會被更新。將日誌更改爲警報,並且您看到DOM未更新。

如果您試圖避免撥打$timeout,您可以使用ngChange事件。與正常的onChange(其在blur上觸發)不同,ngChange將在每次值改變時觸發,例如擊鍵。

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

+0

我對瀏覽器事件循環有一個模糊的概念 - 是什麼意思是「循環」? – KnewB

+1

是的。對於術語上的差異感到抱歉。對我而言[在我的腦海中]事件循環是過程,循環是事件循環的一個實例/運行。 – TheSharpieOne