我目前正在尝试使用 $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');
});
}]);
如果我正在监听当前加载的 Controller 中的事件,它就可以工作。但我的目标是触发当前未加载的其他 Controller /服务中的事件(至少在页面上尚不可见)。通过将 PhaseListener 定义为 testService 的依赖项,我希望它能够在后台加载。
如何通过定义我所拥有的依赖关系来实现这种通信?我无法将 testService 定义为 PhaseListener 的依赖项。 testService 是一个模块示例,可以单独编码并使其可以轻松地与我的应用程序集成。
依赖关系: 服务 1 => 共享服务 <= 服务 2
消息传递: 服务 1 => 共享服务 => 服务 2
最佳答案
服务是单例的,因此虽然确实必须加载它们才能工作,但一旦它们加载,实例化它们就不需要太多成本。你最终不会得到 12 份副本。我每天都使用这种模式,我发现最好让所有服务都依赖于 app.js。在我的主“运行”处理程序中,我注入(inject)了我计划使用的所有主要服务。这保证了它们可用,并且在其他人开始执行任何可能发出事件的操作之前加载它们。加载它们不需要太多 RAM,并且在事件实际触发之前没有工作负载。没有什么理由不这样做 - 服务被设计为全局实体,并且延迟加载它们没有太大值(value)。
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 多个这样的应用程序提供了一个很好的案例。通常在这一点上,您想要重新考虑“管理器”模式实际上为您做什么,而这正是工厂和提供者实际上有用的地方。在那里,您可以让核心服务处理所有发布/订阅工作并管理其中的智能对象,这些对象根据应用程序的状态执行各种特定功能。
模态窗口管理器就是一个很好的例子。您可能有多种类型的模态,它们都有不同的行为。您可以创建一个能够根据参数生成每种类型的主服务,而不是创建三个服务。然后,您可以区分灯箱和“纯”模态,但仍然通过单个服务管理它们。
关于angularjs - Angular 广播无法与独立服务一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25610889/