在app config,angular.js中使用自定义提供程序中的$ http

Kos*_*ika 90 javascript angularjs angular-services

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

主app.js

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

}]);
...
Run Code Online (Sandbox Code Playgroud)

提供者本身

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

我有这样的错误:

Uncaught Error: Unknown provider: $http from services 
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

谢谢!

Dan*_*lev 158

底线是:

  • 无法将服务注入提供程序配置部分.
  • CAN注入服务成初始化提供者的服务的部分.

细节:

Angular框架有一个2阶段初始化过程:

阶段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;
    };
});
Run Code Online (Sandbox Code Playgroud)

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

Uncaught Error: Unknown provider: $http from services 
Run Code Online (Sandbox Code Playgroud)

这个错误实际上说的$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 Code Online (Sandbox Code Playgroud)

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

  • 很好的答案,但虽然它解释了在配置期间如何注入服务是不可能的,但它没有解释如何在配置期间进行HTTP POST/GET.这对于使用API​​提供的值配置的应用程序非常重要. (63认同)
  • @threed:仅当客户端代码来自同一服务器时,才能将配置数据直接插入服务器上的HTML或js.使用CORS,现在可以(并且非常希望)从不同的服务器提供客户端代码,并且从单独的服务器提供数据.在这些情况下,我们需要使用HTTP检索配置数据. (4认同)
  • 虽然这是一个答案,但它不是问题的答案. (4认同)
  • @bebraw&Kosmetika - 我认为在配置阶段你唯一需要请求的是某种设置对象.也许它包含API端点,用户信息,用户的语言环境和语言设置等.如果是这种情况,我建议以某种方式在javascript源中包含该信息.您可以在index.html上使用服务器端呈现来设置一些设置,以便在应用初始化之前它们可用.其他一切,我都试着弄清楚如何在init后做到这一点 (3认同)
  • @Sean:如何制作 HTTP POST/GET 是一个与 OP 不同的问题(是否可以在配置阶段使用 $http?),并且可能完全值得单独发表;由于 Angular 配置阶段的同步特性,向配置代码提供服务器端数据的一个好方法是在服务器端呈现期间将其呈现为 HTML 页面中的 javascript 对象(例如 `<script>var config = < % = mySettings.toJson() %>;</script>`)。这可以使用模板引擎来完成,例如用于 PHP 的 Smarty、用于 Python 的 Jinja2、用于 NodeJS 的 Nunchucks 等。 (2认同)

Cod*_*ody 63

这可能会给你一点杠杆:

var initInjector = angular.injector(['ng']);
var $http = initInjector.get('$http');
Run Code Online (Sandbox Code Playgroud)

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

  • 对于我的提供商来说,"已接受的答案"失败了......我花了两天的挫折试图让这项工作毫无希望.您的方法立即奏效. (6认同)
  • 我确认接受的解决方案不适用于在提供程序中使用$ http.但@Cody的回答确实成功了 (5认同)
  • 这应该是公认的答案.我努力让这个工作起来很努力,这种方法立即解决了我的问题.我认为这可能是一个非常普遍的问题.谢谢@Cody (2认同)