Angularjs 角度广播不与独立服务一起工作
我目前正在尝试使用$rootScope.$broadcast方法来触发angularjs服务中的事件。为此,我创建了一个负责触发事件的服务,并设置了一个不同的服务来拾取事件。重要的是,接收事件的服务应该独立于应用程序的其余部分,这就是我采用共享服务方法的原因 我的广播服务(共享),它在我的应用程序中被调用以触发事件:Angularjs 角度广播不与独立服务一起工作,angularjs,events,service,scope,broadcast,Angularjs,Events,Service,Scope,Broadcast,我目前正在尝试使用$rootScope.$broadcast方法来触发angularjs服务中的事件。为此,我创建了一个负责触发事件的服务,并设置了一个不同的服务来拾取事件。重要的是,接收事件的服务应该独立于应用程序的其余部分,这就是我采用共享服务方法的原因 我的广播服务(共享),它在我的应用程序中被调用以触发事件: angular.module('myModule') .factory('phaseListener', ['$log', '$rootScope', function ($
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');”手动注入服务。此呼叫后,服务将被注入,任何后续广播也将到达新注入的服务。感谢您的详细解释。这证实了我所害怕的。我想我必须在启动时以某种方式连接这些服务。我希望创建某种模块/插件类型的架构,您可以编写自己的服务/控制器并将其插入基础应用程序,而无需更改现有应用程序中的任何内容。看来我必须引入一些虚拟服务来处理所有依赖项。还感谢您对工厂/服务的提示-我一定会看一看。