Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/433.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
Javascript 角度运行块,$rootScope.$on和$state_Javascript_Angularjs_Javascript Events_Typescript_Angular Ui Router - Fatal编程技术网

Javascript 角度运行块,$rootScope.$on和$state

Javascript 角度运行块,$rootScope.$on和$state,javascript,angularjs,javascript-events,typescript,angular-ui-router,Javascript,Angularjs,Javascript Events,Typescript,Angular Ui Router,当我尝试在run块中创建eventhandler时,出现了一个奇怪的问题。要解释这个问题有点困难,部分原因是我不明白发生了什么,但我会尽我所能。这是用打字稿写的 我有以下运行块: angular.module("myapp") .run(($rootScope, StateChangeStartHandler) => { $rootScope.$on("$stateChangeStart", StateChangeStartHandler.handler); }); St

当我尝试在run块中创建eventhandler时,出现了一个奇怪的问题。要解释这个问题有点困难,部分原因是我不明白发生了什么,但我会尽我所能。这是用打字稿写的

我有以下运行块:

angular.module("myapp")
  .run(($rootScope, StateChangeStartHandler) => {
    $rootScope.$on("$stateChangeStart", StateChangeStartHandler.handler);
  });
StateChangeStartHandler是一个简单的angular服务,具有一个名为handler的函数,用于处理$stateChangeStart事件。处理程序服务如下所示:

class StateChangeStartHandler {

  private AuthService;
  private $rootScope;
  private AUTH_EVENTS;

  constructor(AuthService, $rootScope, AUTH_EVENTS
             // Everything breaks if I comment in the following line
             //, $state
             ) {
    this.AuthService = AuthService;
    this.$rootScope = $rootScope;
    this.AUTH_EVENTS = AUTH_EVENTS;
  }

  handler(event, next) {
    if (!this.AuthService.isLoggedIn() && next.name != "root.login") {
      event.preventDefault();
      this.$rootScope.$broadcast(this.AUTH_EVENTS.notAuthenticated);
    }
  }
}

angular.module("myapp")
  .service("StateChangeStartHandler", StateChangeStartHandler);
angular.module("myapp")
  .run(($rootScope, StateChangeStartHandler) => {
    $rootScope.$on("$stateChangeStart", StateChangeStartHandler.handler());
  });
我是用TDD实现的。我编写了一个测试,验证是否在$state上调用了go。当我进入课堂去实现它时,我面临着这个问题。当我在StateChangeStartHandler中注入$state时,突然所有使用$rootScope的测试。$apply()说AuthService.isLoggedIn不是一个函数

我怀疑$rootScope.$apply()触发了$stateChangeStart,然后发生了一些奇怪的事情

更新1: 一个看似无关的测试突然失败的例子:

Chrome 45.0.2454 (Mac OS X 10.10.5) Authentication service login(email, password) should be defined FAILED
    TypeError: this.AuthService.isLoggedIn is not a function
        at StateChangeStartHandler.handler (/Users/blacksails/repos/avalonia/priv/static/js/app.js:305:31)
        at Scope.$broadcast (/Users/blacksails/repos/avalonia/priv/static/js/libraries.js:16311:28)
        at Object.transitionTo (/Users/blacksails/repos/avalonia/priv/static/js/libraries.js:50779:24)
        at Array.<anonymous> (/Users/blacksails/repos/avalonia/priv/static/js/libraries.js:49896:18)
        at Object.invoke (/Users/blacksails/repos/avalonia/priv/static/js/libraries.js:4584:17)
        at handleIfMatch (/Users/blacksails/repos/avalonia/priv/static/js/libraries.js:49386:28)
        at /Users/blacksails/repos/avalonia/priv/static/js/libraries.js:49441:18
        at check (/Users/blacksails/repos/avalonia/priv/static/js/libraries.js:49557:23)
        at update (/Users/blacksails/repos/avalonia/priv/static/js/libraries.js:49566:13)
        at Scope.$broadcast (/Users/blacksails/repos/avalonia/priv/static/js/libraries.js:16311:28)
Chrome 45.0.2454(Mac OS X 10.10.5)身份验证服务登录(电子邮件、密码)应定义失败
TypeError:this.AuthService.isLoggedIn不是函数
StateChangeStartHandler.handler(/Users/blacksails/repos/avalonia/priv/static/js/app.js:305:31)
范围:$broadcast(/Users/blacksails/repos/avalonia/priv/static/js/libraries.js:16311:28)
在Object.transitiono(/Users/blacksails/repos/avalonia/priv/static/js/libraries.js:50779:24)
在阵列上。(/Users/blacksails/repos/avalonia/priv/static/js/libraries.js:49896:18)
在Object.invoke(/Users/blacksails/repos/avalonia/priv/static/js/libraries.js:4584:17)
在handleIfMatch(/Users/blacksails/repos/avalonia/priv/static/js/libraries.js:49386:28)
at/Users/blacksails/repos/avalonia/priv/static/js/libraries.js:49441:18
检查时(/Users/blacksails/repos/avalonia/priv/static/js/libraries.js:49557:23)
更新时(/Users/blacksails/repos/avalonia/priv/static/js/libraries.js:49566:13)
范围:$broadcast(/Users/blacksails/repos/avalonia/priv/static/js/libraries.js:16311:28)
试试这些:

    angular.module("myapp")
    .run(($rootScope, StateChangeStartHandler) => {
      $rootScope.$on
        ("$stateChangeStart",StateChangeStartHandler.handler.bind(StateChangeStartHandler);
    });

我终于解决了。我不太确定技术细节,但我认为这与angular lazy如何加载服务有关。以下步骤解决了我的问题。而不是像这样引用
StateChangeStartHandler
中的函数
handler

angular.module("myapp")
  .run(($rootScope, StateChangeStartHandler) => {
    $rootScope.$on("$stateChangeStart", StateChangeStartHandler.handler);
  });
我让它成为这样的一个获得者:

class StateChangeStartHandler {

  private AuthService;
  private $rootScope;
  private AUTH_EVENTS;

  constructor(AuthService, $rootScope, AUTH_EVENTS
             // Everything breaks if I comment in the following line
             //, $state
             ) {
    this.AuthService = AuthService;
    this.$rootScope = $rootScope;
    this.AUTH_EVENTS = AUTH_EVENTS;
  }

  handler(event, next) {
    if (!this.AuthService.isLoggedIn() && next.name != "root.login") {
      event.preventDefault();
      this.$rootScope.$broadcast(this.AUTH_EVENTS.notAuthenticated);
    }
  }
}

angular.module("myapp")
  .service("StateChangeStartHandler", StateChangeStartHandler);
angular.module("myapp")
  .run(($rootScope, StateChangeStartHandler) => {
    $rootScope.$on("$stateChangeStart", StateChangeStartHandler.handler());
  });

我将函数保存在
StateChangeStartHandler
中的一个字段中,然后
handler
仅返回该函数。在根本不确定的情况下,我怀疑当我像第一个示例中那样传递函数时,
StateChangeStartHandler
及其依赖项没有得到正确初始化。如果有人能解释更多,我会非常高兴。

哪里有
$apply
?为什么需要在
$rootScope
上调用
$apply
?通常是在地方层面上做的,我做了一些承诺测试。实际上,还有很多其他测试也失败了。我有很多使用$httpBackend的测试,所有这些似乎都在$httpBackend.verifyNoOutstandingExpectation()上失败,后者反过来调用Scope.$Digest不会更改所有失败的测试。您需要像这样调用广播:$broadcast($stateChangeStart),data)。你必须打电话给广播,说$on上发生了什么事,而不是另一种方式为什么我要广播$stateChangeStart?Angular ui router已经自动完成了。因为您是这样注册的$。我没有看到任何ui路由器设置。通过广播,您可以“调用”您在$onWell中设置的内容。通过使用$stateChangeStart,我使用ui路由器的事实是显而易见的,我还标记了问题ui路由器。