title: How can I write this function without using $apply() in Angular.js
body: <p>I have a little event hander responding to the up/down keys like this...</p>
  
  <pre><code>    $scope.$on('handleDownKey', function(){ changeIndex(1) });
      $scope.$on('handleUpKey', function(){ changeIndex(-1) });
  
      function changeIndex(val){
          $scope.listIndex += val;
          //$scope.$apply();
      }
  </code></pre>
  
  <p>And in my view I have a list that looks a little like this</p>
  
  <pre><code>&lt;li ng-class="{selected: listIndex == $index}" ng-repeat="item in items"&gt;
      &lt;p&gt;{{item.title}}&lt;/p&gt;
      &lt;p&gt;{{item.desc}}&lt;/p&gt;
  &lt;/li&gt;
  </code></pre>
  
  <p>The issue I have is that changes to <code>listIndex</code> are only reflected in the view when I uncomment the <code>$scope.apply()</code> line. </p>
  
  <p>But when I uncomment that line, I get an <code>Error: $digest already in progress</code> message when the App loads.</p>
  
  <p>My guess is that I'm just not doing this in an Angular way, but how should an example like this be written in Angular?</p>
  
  <p>For those wondering where <code>handleKeyDown</code> comes from, I have a directive that takes keyboard events and passes them to a service called KeyboardSrv. The directive looks like this...</p>
  
  <pre><code>myModule.directive('onKeydown', function(KeyboardSrv) {
      return function(scope, elm, attrs) {
          function applyKeydown() {
            scope.$apply(attrs.onKeydown);
          };           
  
          elm.bind('keydown', function(evt) {
              KeyboardSrv.prepareEvent(evt)
          });
      };
  });
  </code></pre>
  
  <p>And the service looks like this...</p>
  
  <pre><code>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;
  
  };
  </code></pre>