Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 正在调试$apply_Angularjs_Google Chrome Extension - Fatal编程技术网

Angularjs 正在调试$apply

Angularjs 正在调试$apply,angularjs,google-chrome-extension,Angularjs,Google Chrome Extension,我正在使用AngularJS开发一个Chrome扩展(因此它在CSP模式下运行)。amServices.js包含一个处理Chrome本机消息的服务。因此,在js/core/am/amServices.js:268:20中,相关代码如下: chrome.runtime.onMessage.addListener( function (message, sender, sendResponse) { $rootScope.$apply(function () { if (me

我正在使用AngularJS开发一个Chrome扩展(因此它在CSP模式下运行)。amServices.js包含一个处理Chrome本机消息的服务。因此,在js/core/am/amServices.js:268:20中,相关代码如下:

chrome.runtime.onMessage.addListener(
  function (message, sender, sendResponse) {
    $rootScope.$apply(function () {
      if (message.type == 'login' && message.state == 'ok') {
//huge if/else if here for every kind of message
我的理解是,由于这里的所有代码都是异步调用的,并且可以在大多数应用程序视图中触发修改,$rootScope.$apply是必需的。然而,我有时会在控制台中以一种完全随机的方式获得这些信息:

Error: [$rootScope:inprog] http://errors.angularjs.org/1.2.13/$rootScope/inprog?p0=%24apply
    at Error (native)
    at chrome-extension://hbfchfkepmidgcdfcpnodlnmfjhekcom/lib/angular/angular.min.js:6:450
    at n (chrome-extension://hbfchfkepmidgcdfcpnodlnmfjhekcom/lib/angular/angular.min.js:98:34)
    at h.$apply (chrome-extension://hbfchfkepmidgcdfcpnodlnmfjhekcom/lib/angular/angular.min.js:104:195)
    at chrome-extension://hbfchfkepmidgcdfcpnodlnmfjhekcom/js/core/am/amServices.js:268:20
    at Function.target.(anonymous function) (extensions::SafeBuiltins:19:14)
    at Event.dispatchToListener (extensions::event_bindings:394:22)
    at Event.dispatch_ (extensions::event_bindings:378:27)
    at Event.dispatch (extensions::event_bindings:400:17)
    at messageListener (extensions::messaging:192:31) 
不,让我感到不安的是,与这里所解释的不同:

在堆栈跟踪中,我没有看到两个$apply调用,因此我无法知道冲突来自何处。另外,我不能运行AngularJS Batarang调试工具,因为它不能在CSP模式下工作


我忽略了这些错误,没有任何明显的后果,但我不确定忽略它们是否真的安全。关于如何知道哪两个apply调用触发了冲突,您有什么想法吗?

如果您的问题是为什么?您希望只有当您有多个
$apply()

正如@J.Wells在对您的问题的评论中提到的,可能是因为其他
angular
指令触发了
$scope.$apply
chrome.runtime
的回调发生在angular内部处于
$$阶段时

查看一下for
ng click
,angularjs内部使用相同的
$scope.$apply
,可供开发人员使用

<> P> >仅考虑角度指令,如<代码> NG点击,<代码> NG更改使用$Actudio评估表达式。$Apple,启动<代码> $Apdio< <代码>阶段,以及指令如<代码> NG如果和<代码> NG隐藏< /代码>使用$范围。 错误的理论,因为正如@Wawy所建议的,javascript是单线程的,因此在摘要中无法执行回调(左键,以便注释有意义):
如果在单击登录按钮时出现这种情况,并带有
ng click
指令,可能是因为chrome在
ng click
$digest
阶段完成之前绑定和响应过快,因此执行了
onMessage
回调。

要回答这个问题,我们需要看看$digest和$apply的实现:

$digest: function() {
    //Simplified code

    beginPhase('$digest'); 
    /* $$phase = 'digest' 
       From now on any code that calls $apply will cause an exception.
    */

    lastDirtyWatch = null;

    do { // "while dirty" loop
      dirty = false;
      current = target;

      //Running any $evalAsync your code might have called
      while(asyncQueue.length) {
        try {
          asyncTask = asyncQueue.shift();
           // If any $evalAsync expression calls $apply will cause an exception.
          asyncTask.scope.$eval(asyncTask.expression);
        } catch (e) {
          clearPhase();
          $exceptionHandler(e);
        }
        lastDirtyWatch = null;
      }

      traverseScopesLoop:
      do { // "traverse the scopes" loop
        if ((watchers = current.$$watchers)) {
          // process our watches
          // If any $watch expression calls $apply it will cause an exception.
          ...
        }
      } while ((current = next));

    } while (dirty || asyncQueue.length);
}
$apply:

$apply: function(expr) {
        try {
          beginPhase('$apply');
          //Any code inside expr that calls $apply or any function that does it will cause an exception.
          return this.$eval(expr);
        } catch (e) {
          $exceptionHandler(e);
        } finally {
          clearPhase();
          try {
            $rootScope.$digest();
          } catch (e) {
            $exceptionHandler(e);
            throw e;
          }
        }
      },
在分析了这两种方法后,我们发现了3个可能导致异常的地方:

$evalAsync表达式、$watch表达式和$apply表达式。因此,这些表达式中直接或间接调用$apply的任何代码都将触发异常


值得一提的是,angular在内部也调用$apply,因此如果您在angular“领域”内,就不应该调用$apply。

我要做的一件事是使用angular的非精简版本,并查看其内部状态。它可能会变得复杂,但我有一些这样的调试想法。错误是说已经有一个$digest/$apply正在进行中。这类事情发生在听众触发摘要而不是订阅摘要时。Angular只在$digest中工作,因此如果Angular应用程序中发生了某些事情,则$digest/$apply已在程序中。您很可能可以使用$watch和/或$broadcast/$emit完成您想要完成的任务。很难在不知道更多的情况下给出进一步的建议。另外-$apply calls$digest(以防我没有正确地澄清)。你们甚至读过你们评论的问题吗?我知道错误的意思,也知道为什么会发生。问题是为什么堆栈跟踪没有显示两个不同的apply调用。哦,伙计-很抱歉,我们回答了一个您返回并编辑的问题。为了回答你评论中的问题,这里有$apply
$apply:function(expr){try{beginPhase('$apply');返回这个。$eval(expr);}catch(e){$exceptionHandler(e);}最后是{clearPhase();try{$rootScope.$digest();}catch(e){$exceptionHandler(e);throw e;}}}
这就是为什么,genius。一个$digest对于应用程序是全局的,而不是特定于一个指令。它也是一个同步操作(就我而言,javascript是单线程的),因此我认为在执行$digest中的代码时不可能发生回调。$rootScope。$digest对于应用程序来说是全局的,但每个$scope都有自己的$digest。