我有一个小事件处理器响应这样的上/下键......
$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>
我遇到的问题是listIndex
的更改只会在我取消注释$scope.apply()
行时反映在视图中。
但是当我取消注释该行时,我会在应用程序加载时收到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;
};
答案 0 :(得分:0)
因此有一种方法可以在Angular中处理此问题而不会触发错误。基本上,只要角度运行$digest
,它就会获得此更改。我在这里遇到的问题是我的changeIndex
方法未触发$digest
,因此我必须手动调用$apply
。
但是,当应用启动时,会调用changeIndex
方法,而$digest
仍在运行,这会触发错误,因为您无法在另一个内部调用$digest
致电$digest
。
Angular确实提供了一种方法来告诉当前正在运行的$digest
,因此应该像这样处理对$apply
的调用......
$scope.listIndex += val
if(!$$phase) $scope.$apply();
如果$$phase
为真,则当前角度为$digest
,我们的更改将自动获取。如果$$phase
为false,则我们需要手动触发$apply
。
虽然这是一个修复,但我仍然宁愿不必手动调用$ apply。它感觉有点太像手动引用计数,并且使用这种方式工作的方法对我来说闻起来很有趣。