使用typeahead插件时,$ apply已在进行中出错(发现与ng-focus + ng-blur相关)

时间:2014-03-27 20:03:41

标签: angularjs angularjs-scope

我的主要问题是错误没有指向我的代码中的任何地方,我们的项目中没有那么多$apply次调用。 似乎生成错误的代码:

 <input type="text" 
  placeholder="{{ $root.pg.t('HEADER.CITY_OR_POSTAL') }}"
  data-ng-focus="decideToStop();" data-ng-blur="decideToStart()"
  data-ng-model="search.selected" 
  typeahead-on-select="search.locationQuery(geo_locations, search.selected)" 
  typeahead="location.name for location in getLocations($viewValue) | filter: $viewValue | limitTo:8" class="semi-bold">

在控制器中:

$scope.decideToStop = function(){
  if($scope.actionTimeout){
    $timeout.cancel($scope.actionTimeout);
    $scope.actionTimeout = {};
  }


  $scope.MyService.CustomMethodThatDoesALotOfThings();
};


$scope.decideToStart = function(){
  if(CustomCondition()){
    $scope.actionTimeout = $timeout(function(){
      $scope.MyService.AnotherCustomMethodThatDoesALotOfThings();

    }, 150);

  }
};

$root.pg只是服务中的polyglot.js库,暂时放在rootScope中。 search是与位置搜索相对应的服务。

我在输入字段中更改城市时收到错误。我不知道如何调试这个......

1 个答案:

答案 0 :(得分:12)

这是同时使用ng-focus和其他事件指令的问题。大多数情况下,当您使用其中一个事件指令(ng-click,ng-blur)来聚焦具有ng-focus的元素时,就会发生这种情况。它实际上是一个错误,但您可以轻松修复它。最好的选择是编写自己的指令,应用函数async:

app.directive('ngFocusAsync', ['$parse', function($parse) {
  return {
    compile: function($element, attr) {
      var fn = $parse(attr.ngFocusAsync);
      return function(scope, element) {
        element.on('focus', function(event) {
          scope.$evalAsync(function() {
            fn(scope, {$event:event});
          });
        });
      };
    }
  };
}]

如果您不想这样做,您可以获取该指令的内容并手动将其应用于您的元素,但由于该指令非常小,因此该指令更可取。当它在核心中得到修复时,您可以简单地替换所有声明。

在此处查看示例:http://plnkr.co/edit/GBdvtN6ayo59017rLKPs?p=preview 如果使用ng-focus替换ng-focus-async,则在单击按钮时或在模糊第二个输入字段时会出现角度。