Angular:可选配置一个服务

Angular: Optionally configure a service

我有一个服务,它有一个指令名称的内部列表(我们称之为 listService)。本着松耦合应用程序的精神,我希望其他模块能够将自己的指令添加到该列表,而不是在服务模块中静态定义它。

我知道我可以创建一个提供商来配置这样的服务:

app.provider("listService", ServiceProvider);

app.config(["listServiceProvider", function(listServiceProvider) {
    listServiceProvider.add("myDirective");
}]);

同时,我不希望所有定义指令的模块都依赖于服务。所以我想做的是 "if this service is used in this project: configure it; else: ignore".

不幸的是,上面的代码产生了 module error if listServiceProvider is not available. I also tried to use a decorator 相同的结果。

那么我如何可选配置服务以获得松散耦合的应用程序?

就像我在评论中提到的,重要的是要有一个更广泛的上下文来解释为什么你需要注册指令(或它们的名称)。

在没有更广泛的理解的情况下,一般来说,如果您需要有条件地检查服务(或服务提供者,在配置中)是否存在,您可以使用 $injector:

.config(function($injector){
   var listServiceProvider;
   if ($injector.has("listServiceProvider")) {
     listServiceProvider = $injector.get("listServiceProvider");
   }

   if (listServiceProvider){
     listServiceProvider.add("myDirective");
   }
});

如果我没理解错的话;您需要一个服务来跟踪您的哪些指令已添加到 Angular 应用程序中,并且指令和服务彼此分离,以便可以按需包含它们。

我认为模块模式不会为您做这件事,因为服务和指令是在加载时注入的。可选的依赖项注入是不可能的。

但是,您可以从您的指令中触发一个事件并在您的服务中获取它,从而完全消除依赖注入的需要。

我的指令

.run(['$rootScope', 'LIST_SERVICE_EVENT', 
          function($rootScope, LIST_SERVICE_EVENT) {
    $rootScope.$emit(LIST_SERVICE_EVENT, 'myDirective');
}]);

listService

.run(['listService', '$rootScope', 'LIST_SERVICE_EVENT', 
        function(listService, $rootScope, LIST_SERVICE_EVENT) {
    $rootScope.$on(LIST_SERVICE_EVENT, function(ev, name) {
        listService.add(name);
    });
}]);

Fiddle: http://jsfiddle.net/bdpxhLg3/4/.