我是棱角分明的新人并遇到了一个问题22:
事实:
我有一个记录我的东西的服务(我的记录器).
我用我自己的实现替换了$ ExceptionHandler(angular),它将未捕获的异常转发给my-logger服务
我有另一个服务,推送服务,只要在我的应用程序中使用'my-logger'记录致命消息时需要通知.
问题:
我不能让'my-logger'依赖'推送',因为它会创建循环依赖(因为'推送'使用$ http.圆圈:$ ExceptionHandler - > my-logger - >推送器 - > $ http - > $的ExceptionHandler ...)
我的尝试:
为了使这两个服务相互通信,我想在推送服务上使用$ watch:在$ rootscope上查看将在my-logger中更新的属性.但是,当尝试在'my-logger'中使用$ rootScope时,为了更新'pusher'"监视"的属性,我在循环依赖上失败,因为事实证明$ rootscope依赖于$ ExceptionHandler(圆圈) :$ ExceptionHandler - > my-logger - > $ rootScope - > $ ExceptionHandler).
试图找到一个选项,在运行时获取其上下文"my-logger"服务工作的范围对象.找不到这样的选择.
也不能使用广播,因为它需要my-logger来访问作用域($ rootScope),这是不可能的,如上所示.
我的问题:
是否有一种有角度的方式让两个服务通过第三方实体进行通信?
知道如何解决这个问题吗?
Mar*_*cok 10
使用充当通知/ pubsub服务的第3个服务:
.factory('NotificationService', [function() {
var event1ServiceHandlers = [];
return {
// publish
event1Happened: function(some_data) {
angular.forEach(event1ServiceHandlers, function(handler) {
handler(some_data);
});
},
// subscribe
onEvent1: function(handler) {
event1ServiceHandlers.push(handler);
}
};
}])
Run Code Online (Sandbox Code Playgroud)
上面,我只显示一个事件/消息类型.每个附加事件/消息都需要自己的数组,发布方法和订阅方法.
.factory('Service1', ['NotificationService',
function(NotificationService) {
// event1 handler
var event1Happened = function(some_data) {
console.log('S1', some_data);
// do something here
}
// subscribe to event1
NotificationService.onEvent1(event1Happened);
return {
someMethod: function() {
...
// publish event1
NotificationService.event1Happened(my_data);
},
};
}])
Run Code Online (Sandbox Code Playgroud)
Service2将与Service1类似地编码.
请注意$ rootScope,$ broadcast和scope如何不与此方法一起使用,因为它们不需要与服务间通信.
通过上述实现,服务(一旦创建)保持订阅应用程序的生命周期.您可以添加处理取消订阅的方法.
在我当前的项目中,我使用相同的NotificationService来处理控制器范围的pubsub.(如果感兴趣,请参阅更新Angularjs和Momentjs中的"time ago"值).
是的,使用事件和听众.
在"我的记录器"中,您可以在捕获新日志时广播事件:
$rootScope.$broadcast('new_log', log); // where log is an object containing information about the error.
Run Code Online (Sandbox Code Playgroud)
而不是在你的'推动者'中听取那个事件:
$rootScope.$on('new_log', function(event, log) {... //
Run Code Online (Sandbox Code Playgroud)
这样您就不需要任何依赖项.