我已经编写了一个简单的例子,我想从服务发出/广播事件,我希望控制器收听该事件并更改UI,但我无法使其工作并调试代码似乎停在听众中,但它没有执行该功能。

http://plnkr.co/edit/eglcq7zellfkp86dyzoe?p=preview

服务:

angular.module('ServiceModule', []).
service('servicetest', ['$rootScope', function($rootScope){
    this.test = function(){
      $rootScope.$emit('testevent');
    };
}]);
.

控制器

angular.module('ControllerModule', ['ServiceModule']).
    controller('ControllerTest', ['$scope','$rootScope','servicetest', function($scope, $rootScope, servicetest){
      $scope.name = 'World';
      servicetest.test();
      $rootScope.$on('testevent', function(){
        $scope.name = 'Joe';
      });
    }]);
.

索引

<!DOCTYPE html>
<html ng-app="ControllerModule">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.2.x" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js" data-semver="1.2.16"></script>
    <script src="controller.js"></script>
    <script src="service.js"></script>
  </head>

  <body ng-controller="ControllerTest">
    <p>Hello {{name}}!</p>
  </body>

</html>
.

解决方案:

作为Ivarni或Walter品牌报道,触发事件的服务函数的调用必须放在侦听器之后,如果不是您触发了能够尚未侦听的事件。

我们只需要更改控制器,如下所示:

服务

angular.module('ControllerModule', ['ServiceModule']).
        controller('ControllerTest', ['$scope','$rootScope','servicetest', function($scope, $rootScope, servicetest){
          $scope.name = 'World';
          $rootScope.$on('testevent', function(){
            $scope.name = 'Joe';
          });
          servicetest.test();
        }]);
.

有帮助吗?

解决方案

您在附加侦听器之前触发事件。

试试:

  $rootScope.$on('testevent', function(){
    $scope.name = 'Joe';
  });
  servicetest.test();
.

其他提示

只是将侦听器下方的serviceTest.test()放在控制器中,如下所示:

  $rootScope.$on('testevent', function(){
    $scope.name = 'Joe';
  });
  servicetest.test();
.

在调用test()之后,您将侦听器附加,只需忘记事件。

我发现在中等大小的应用程序中最好的解决方案是在$发出函数周围创建包装器,并延迟$几毫秒的$ emit,足以让所有要注册的事件。

您还可以在包装器中介绍一些更好的东西,就像将其传递它当前$ scope,或者让它创建$ rootscope的新子范围(它在下面的一个级别,因此在传播时仍然仍然快。最多$ rootscope),并使用它作为数据通道,范围内的事件破坏,等等...

这是整个源代码: http://jsfiddle.net/gabrielcatalin/2urr7

和这是一个摘录:

/**
 * Waits a given amount of time before calling emitting
 * This works well when the event registration happens before emitting.
 *
 * @param name
 * @param fn
 * @param wait
 */
this.delayEmit = function (name, fn, wait) {
    // Because of the $scope's lifecycle the $emit(publish) happens after the $on(subscription)
    //  therefore that needs to be taken care of with a delay
    $timeout(function () {
        self.emit(name, fn);
    }, wait || 100);
}
.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top