Angularjs 角度广播不与独立服务一起工作

Angularjs 角度广播不与独立服务一起工作,angularjs,events,service,scope,broadcast,Angularjs,Events,Service,Scope,Broadcast,我目前正在尝试使用$rootScope.$broadcast方法来触发angularjs服务中的事件。为此,我创建了一个负责触发事件的服务,并设置了一个不同的服务来拾取事件。重要的是,接收事件的服务应该独立于应用程序的其余部分,这就是我采用共享服务方法的原因 我的广播服务(共享),它在我的应用程序中被调用以触发事件: angular.module('myModule') .factory('phaseListener', ['$log', '$rootScope', function ($

我目前正在尝试使用$rootScope.$broadcast方法来触发angularjs服务中的事件。为此,我创建了一个负责触发事件的服务,并设置了一个不同的服务来拾取事件。重要的是,接收事件的服务应该独立于应用程序的其余部分,这就是我采用共享服务方法的原因

我的广播服务(共享),它在我的应用程序中被调用以触发事件:

angular.module('myModule')
  .factory('phaseListener', ['$log', '$rootScope',  function ($log, $rootScope) {

    var phaseListener= {};

    phaseListener.broadcastPhase = function(phase) {
      $rootScope.$broadcast('test');
    };

    return phaseListener;
}]);
在下面的服务“testService”中,我正在侦听此事件,但它没有被触发。我正在从另一个服务调用broadcastPhase()方法,该方法将被触发

angular.module('myModule')
  .factory('testService', [ '$rootScope', '$scope', '$log', 'phaseListener', 
    function ($rootScope, $scope, $log, phaseListener) {   

    $rootScope.$on('test', function() {
      $log.debug('This works');
    });

  }]);
如果我在当前加载的控制器中侦听事件,它将正常工作。但我的目标是在当前未加载的其他控制器/服务中触发事件(至少在页面上还不可见)。通过将phaseListener定义为testService的依赖项,我希望它能在后台加载

如何通过定义现有的依赖项来实现这种通信?我不能将testService定义为phaseListener的依赖项。testService是一个可以单独编码的模块示例,它允许轻松地与我的应用程序集成

依赖项:
服务1=>共享服务SharedService=>服务2

服务是单例的,因此,虽然必须加载它们才能工作,但一旦加载,实例化它们的成本就不会太高。你不会有12份拷贝的。我每天都在使用这种模式,我发现最好是让app.js的所有服务都依赖于app.js。在我的主“run”处理程序中,我注入了我计划使用的所有主要服务。这保证了它们是可用的,并且在其他任何人开始执行任何可能发出事件的操作之前加载它们。加载它们不需要太多RAM,而且在实际触发事件之前不会有工作负载。没有什么理由不这样做——服务被做成了全局实体,懒散地加载它们没有多大价值

angular.module('myApp', ['myService1', 'myService2', 'myService3'])
.run(['$rootScope', 'myService1', 'myService2', 'myService3', function() {
    // NOTE: You may or may not actually need to do anything here. But by asking the
    // injector for each service you can guarantee that they're loaded when the app
    // starts. That lets them set up any listeners necessary for them to function.
    // Note that the order in which you ask for them here will determine the order in
    // which they're instantiated!
});

你也可以考虑使用“服务”而不是“工厂”。你没有利用两者之间的差异,因此工厂不会给你任何好处。服务基本上只是工厂“您通常希望这样…”机制的简写,如果改用服务,您将保存两行代码(

var
定义和
return
语句):

angular.module('myModule')
    .service('phaseListener', ['$log', '$rootScope',  function ($log, $rootScope) {
        this.broadcastPhase = function(phase) {
            $rootScope.$broadcast('test');
        };
    }]);
如果需要,您仍然可以在服务中定义作用域局部变量,但这是可选的

唯一一次我不会这么做是如果有几十个。。。但在这种情况下,我会质疑应用程序的架构。我正在构建一个极其复杂的应用程序,开发周期为6个月,到目前为止我们只有9项服务。这只是一个轶事,但我仍然会惊讶地看到有人提出了一个有30多个应用程序的好例子。通常在这一点上,你需要重新考虑“经理”模式实际上为你做了什么,而这正是工厂和供应商真正有用的地方。在那里,您可以让核心服务处理所有发布/订阅工作,并管理其中的智能对象,这些智能对象根据应用程序的状态执行各种特定功能


一个很好的例子是模态窗口管理器。你可能有几种不同行为的情态动词。您可以创建一个能够基于参数生成每种类型的主服务,而不是创建三个服务。然后,您可以区分lightbox和“纯”modals,但仍然可以通过一个服务来管理它们。

我找到了一种实现我所寻找的功能的简洁方法。也许有人可以使用它:因为我不知道启动时必须收听广播事件的所有服务,所以我不能像在angular中通常那样添加依赖项。相反,我可以在运行时通过“$injector.get('serviceName');”手动注入服务。在此之后,服务被注入,任何后续广播也将到达新注入的服务。

由于这些控制器/服务未加载,因此侦听器上的
$也未加载。所以这永远不会奏效。您必须确保服务或控制器功能已运行,您希望它们“侦听”事件。如果我无法在phaseListener服务中添加依赖项,我如何才能最好地做到这一点?我个人会在触发某个事件后使用UI路由器更改应用程序的“状态”。状态为可与控制器/服务/模板耦合。我找到了一个巧妙的方法来实现我所追求的目标。也许有人可以使用它:因为我不知道启动时必须收听广播事件的所有服务,所以我不能像在angular中通常那样添加依赖项。相反,我可以在运行时通过“$injector.get('serviceName');”手动注入服务。此呼叫后,服务将被注入,任何后续广播也将到达新注入的服务。感谢您的详细解释。这证实了我所害怕的。我想我必须在启动时以某种方式连接这些服务。我希望创建某种模块/插件类型的架构,您可以编写自己的服务/控制器并将其插入基础应用程序,而无需更改现有应用程序中的任何内容。看来我必须引入一些虚拟服务来处理所有依赖项。还感谢您对工厂/服务的提示-我一定会看一看。