90

主要问题 - 有可能吗?我试过没有运气..

主应用程序.js

...
var app = angular.module('myApp', ['services']);
app.config(['customProvider', function (customProvider) {

}]);
...

提供者本身

var services = angular.module('services', []);
services.provider('custom', function ($http) {
});

我有这样的错误:

Uncaught Error: Unknown provider: $http from services 

有任何想法吗?

谢谢!

4

4 回答 4

158

底线是:

  • 不能将服务注入提供程序配置部分
  • 您可以将服务注入到初始化提供者服务的部分

细节:

Angular 框架有两个阶段的初始化过程:

阶段 1:配置

在这个config阶段,所有的提供者都被初始化并且所有的config部分都被执行。这些config部分可能包含配置提供程序对象的代码,因此可以将它们注入提供程序对象。但是,由于提供者是服务对象的工厂,并且在此阶段提供者尚未完全初始化/配置 -> 在此阶段您不能要求提供者为您创建服务 -> 在配置阶段您不能使用/注入服务。此阶段完成后,所有提供程序都准备就绪(配置阶段完成后无法再进行提供程序配置)。

第 2 阶段:运行

run阶段期间,所有run部分都被执行。在此阶段,提供者已准备好并可以创建服务 -> 在此run阶段您可以使用/注入服务

例子:

1. 将服务注入$http提供者初始化函数不起作用

//ERRONEOUS
angular.module('myModule').provider('myProvider', function($http) {
    // SECTION 1: code to initialize/configure the PROVIDER goes here (executed during `config` phase)
    ...

    this.$get = function() {
        // code to initialize/configure the SERVICE goes here (executed during `run` stage)

        return myService;
    };
});

由于我们试图将$http服务注入到在该config阶段执行的函数中,我们将得到一个错误:

Uncaught Error: Unknown provider: $http from services 

这个错误实际上是在说$httpProvider用于创建$http服务的那个还没有准备好(因为我们仍处于config阶段)。

2.将服务注入$http服务初始化函数起作用:

//OK
angular.module('myModule').provider('myProvider', function() {
    // SECTION 1: code to initialize/configure the PROVIDER goes here (executed during `config` phase)
    ...

    this.$get = function($http) {
        // code to initialize/configure the SERVICE goes here (executed during `run` stage)

        return myService;
    };
});

由于我们现在将服务注入到服务初始化函数中,该函数在run阶段执行,因此该代码将起作用。

于 2013-07-06T07:16:07.433 回答
64

这可能会给你一点筹码:

var initInjector = angular.injector(['ng']);
var $http = initInjector.get('$http');

但要小心,成功/错误回调可能会让您在应用程序启动和服务器响应之间处于竞争状态。

于 2014-02-03T20:16:42.170 回答
1

这是一个老问题,如果我们想依赖库的核心能力,似乎我们有一些鸡蛋的事情。

我没有从根本上解决问题,而是绕过。创建一个包裹整个主体的指令。前任。

<body ng-app="app">
  <div mc-body>
    Hello World
  </div>
</body>

现在mc-body需要在渲染之前初始化(一次),例如。

link: function(scope, element, attrs) {
  Auth.login().then() ...
}

Auth是服务或提供者,例如。

.provider('Auth', function() {
  ... keep your auth configurations
  return {
    $get: function($http) {
      return {
        login: function() {
          ... do something about the http
        }
      }
    }
  }
})

在我看来,我确实可以控制引导程序的顺序,这是在常规引导程序解析所有提供程序配置然后尝试初始化mc-body指令之后。

在我看来,这个指令可以领先于路由,因为路由也是通过指令 ex 注入的。<ui-route />. 但我可能是错的。需要更多调查。

于 2017-08-11T21:32:42.757 回答
-2

在回答您的问题“有什么想法吗?”时,我会回答“是”。但是等等,还有更多!

我建议只在配置中使用 JQuery。例如:

var app = angular.module('myApp', ['services']);
app.config(['$anyProvider', function ($anyProvider) {
    $.ajax({
        url: 'www.something.com/api/lolol',
        success: function (result) {
            $anyProvider.doSomething(result);
        }
    });
}]);
于 2016-11-01T18:54:34.167 回答