Angular run block,$ rootScope。$ on和$ state

时间:2015-09-19 14:58:33

标签: javascript angularjs javascript-events typescript angular-ui-router

当我尝试在运行块中创建一个eventhandler时,我遇到了一个奇怪的问题。这个问题有点难以解释,部分原因是我不明白发生了什么,但我会尽力而为。它是用打字稿写的。

我有以下运行块:

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

StateChangeStartHandler是一个简单的角度服务,带有一个名为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);

我正在使用TDD实现这一点。我写了一个测试,验证是否调用了$ state。当我进入课堂实施它时,我遇到了这个问题。当我在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)

2 个答案:

答案 0 :(得分:0)

试试这些:

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

答案 1 :(得分:0)

我终于解决了它。我不太确定技术细节,但我认为这与角度延迟加载服务有关。以下解决了我的问题。而不是像这样引用handler中的函数StateChangeStartHandler

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

我这样做了一个吸气剂:

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

我将函数保存在StateChangeStartHandler的字段中,然后handler仅返回该函数。根本没有确定,我怀疑当我像第一个例子中那样传递函数时,StateChangeStartHandler并且它的依赖关系没有得到正确的初始化。如果有人可以解释更多关于这一点,我会很高兴。