[英]How can I write this function without using $apply() in Angular.js
我有一個小事件處理程序,像這樣響應上/下鍵...
$scope.$on('handleDownKey', function(){ changeIndex(1) });
$scope.$on('handleUpKey', function(){ changeIndex(-1) });
function changeIndex(val){
$scope.listIndex += val;
//$scope.$apply();
}
在我看來,我有一個看起來像這樣的列表
<li ng-class="{selected: listIndex == $index}" ng-repeat="item in items">
<p>{{item.title}}</p>
<p>{{item.desc}}</p>
</li>
我的問題是,僅在取消注釋$scope.apply()
行時,對listIndex
更改才會反映在視圖中。
但是,當我取消注釋該行時, Error: $digest already in progress
加載應用程序時收到Error: $digest already in progress
消息Error: $digest already in progress
。
我的猜測是我不是以Angular的方式進行操作,但是如何用Angular編寫這樣的示例?
對於那些想知道handleKeyDown
來自何處的人,我有一條指令可以接收鍵盤事件並將它們傳遞給名為KeyboardSrv的服務。 指令看起來像這樣...
myModule.directive('onKeydown', function(KeyboardSrv) {
return function(scope, elm, attrs) {
function applyKeydown() {
scope.$apply(attrs.onKeydown);
};
elm.bind('keydown', function(evt) {
KeyboardSrv.prepareEvent(evt)
});
};
});
服務看起來像這樣...
function KeyboardSrv($rootScope){
var KeyboardSrv = {};
KeyboardSrv.code;
KeyboardSrv.evt;
KeyboardSrv.prepareEvent = function(evt){
KeyboardSrv.code = evt.which;
KeyboardSrv.evt = evt;
if(KeyboardSrv.code == 40){
KeyboardSrv.broadcastEvent("handleDownKey", evt);
}
if(KeyboardSrv.code == 38){
KeyboardSrv.broadcastEvent("handleUpKey", evt);
}
}
KeyboardSrv.broadcastEvent = function(msg, event){
$rootScope.$broadcast(msg, event);
}
return KeyboardSrv;
};
因此,有一種方法可以在Angular中處理此問題而不會觸發錯誤。 基本上,angular在運行$digest
時都會接受此更改。 我這里的問題是我的changeIndex
方法沒有觸發$digest
,所以我必須手動調用$apply
。
但是,在應用程序啟動時,將changeIndex
方法,而$digest
仍在運行,這會引發錯誤,因為您無法在$digest
另一個調用中調用$digest
。
Angular確實提供了一種方法來告知$digest
當前是否正在運行,因此應像這樣處理對$apply
的調用...
$scope.listIndex += val
if(!$$phase) $scope.$apply();
如果$$phase
為真,則angular當前運行$digest
,我們的更改將自動進行。 如果$$phase
為假,則需要手動觸發$apply
。
雖然這是一個修復程序,但我仍然希望不必手動調用$ apply。 感覺有點像手動引用計數,並擁有以這種方式工作的方法,這對我來說很有趣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.