使用ui.bootstrap范围。$ watch& element.triggerHandler - getting - 错误:[$ rootScope:inprog] $ digest已在进行中

时间:2014-02-09 18:19:56

标签: angularjs angular-ui-bootstrap

当表单字段无效时,我做了几个指令来使bootstrap popovers发生。我遇到的唯一障碍是试图“评估”属性值为true或false,因此我可以调用open或close popover。我是一个有角度的新手(只是学习),但做了一些研究,似乎使用$ scope.watch是要使用的东西(以及查看ng-show和ng-hide代码)。所以一切都很好用,直到我尝试从$ scope.watch中调用element.triggerHandler()并使用bootstrap.ui。

这是我的指示:

app.directive('tooltipTriggerOn', ['$log', function($log) {
  function link(scope, element, attrs) {
    scope.$watch(attrs.tooltipShow, function(val) {
        if (val) {
          $log.info('trigger openPopup');
        } else {
          $log.info('trigger closePopup');
        }
      //if (val) element.triggerHandler('openPopup');
      //else element.triggerHandler('closePopup');
    });
  }
  return {
    restrict: 'A',
    link: link
  };
}]);

if / else已注释掉,使应用程序无问题地运行。如果我启用这些行,我会收到javascript错误:

Error: [$rootScope:inprog] $digest already in progress
Error: a.$apply(...) is not a function

但为什么呢?当我不使用ui.bootstrap时,这个小方案工作正常。所以:

  1. 是否有使用范围的技巧。$ watch在我的指令中并没有得到错误?
  2. 是否有不同的方法来“评估”指令属性而不使用范围。$ watch?
  3. 为什么会发生这种错误?
  4. 以下是插件:

    这个演示了bootstrap.ui的问题,只是取消注释问题中描述的违规if语句。

    plunkr

    这个演示了$ scope.watch在没有bootstrap.ui的情况下工作

    plunkr

    任何帮助表示赞赏!

    - 迈克

1 个答案:

答案 0 :(得分:2)

当我遇到$digest already in progress错误,并且我无法以另一种方式重写代码以避免问题时,我将$timeout(function(){...})包裹起来。这会导致包装的代码在当前摘要周期之后执行(因此它不在进行中)。

另请参阅“AngularJS : Prevent error $digest already in progress when calling $scope.$apply()”(第二次回复)

  $timeout(function(){
    if (val) element.triggerHandler('openPopup');
    else element.triggerHandler('closePopup');
  });

工作演示:http://plnkr.co/edit/STaPZI2f9eTaRhnsr6Qm?p=preview