angular JS - 非依赖服务之间的通信

avi*_*hen 13 angularjs

我是棱角分明的新人并遇到了一个问题22:

事实:

  1. 我有一个记录我的东西的服务(我的记录器).

  2. 我用我自己的实现替换了$ ExceptionHandler(angular),它将未捕获的异常转发给my-logger服务

  3. 我有另一个服务,推送服务,只要在我的应用程序中使用'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"值).


Ste*_*wie 6

是的,使用事件和听众.

在"我的记录器"中,您可以在捕获新日志时广播事件:

$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)

这样您就不需要任何依赖项.