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

时间:2021-08-29 12:16:28

The main question - is it possible? I tried with no luck..

主要的问题是——这可能吗?我真没想到…

main app.js

主要app.js

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

}]);
...

provider itself

提供者本身

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

And I've got such error:

我有这样的错误:

Uncaught Error: Unknown provider: $http from services 

Any ideas?

什么好主意吗?

Thanks!

谢谢!

4 个解决方案

#1


154  

The bottom line is:

  • You CANNOT inject a service into the provider configuration section.
  • 不能将服务注入到provider configuration部分。
  • You CAN inject a service into the section which initializes the provider's service.
  • 可以将服务注入初始化提供者服务的部分。

Details:

Angular framework has a 2 phase initialization process:

角框架有两阶段初始化过程:

PHASE 1: Config

During the config phase all of the providers are initialized and all of the config sections are executed. The config sections may contain code which configures the provider objects and therefore they can be injected with provider objects. However, since the providers are the factories for the service objects and at this stage the providers are not fully initialized/configured -> you cannot ask the provider to create a service for you at this stage -> at the configuration stage you cannot use/inject services. When this phase is completed all of the providers are ready (no more provider configuration can be done after the configuration phase is completed).

在配置阶段中,所有的提供者都被初始化,所有的配置部分都被执行。配置部分可能包含配置提供程序对象的代码,因此可以将它们注入提供程序对象。但是,由于提供程序是服务对象的工厂,而且在此阶段,提供程序还没有完全初始化/配置——您不能要求提供程序在此阶段为您创建服务——在配置阶段不能使用/注入服务的>。当这个阶段完成时,所有的提供者都准备好了(在配置阶段完成后,不能再进行提供者配置)。

PHASE 2: Run

During run phase all the run sections are executed. At this stage the providers are ready and can create services -> during run phase you can use/inject services.

在运行阶段,将执行所有的运行部分。在这个阶段,提供程序已经准备好,可以在运行阶段创建服务——>,您可以使用/注入服务。

Examples:

1. Injecting the $http service to the provider initialization function WILL NOT work

//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;
    };
});

Since we are trying to inject the $http service into a function which is executed during the config phase we will get an error:

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

Uncaught Error: Unknown provider: $http from services 

What this error is actually saying is that the $httpProvider which is used to create the $http service is not ready yet (since we are still in the config phase).

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

2. Injecting the $http service to the service initialization function WILL work:

//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;
    };
});

Since we are now injecting the service into the service initialization function, which is executed during run phase this code will work.

由于我们现在将服务注入到服务初始化函数中,该函数在运行阶段执行,所以这段代码将有效。

#2


59  

This might give you a little leverage:

这可能会让你有一些优势:

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

But be careful, the success/error callbacks might keep you in a race-condition between the app start and the server response.

但是要小心,成功/错误回调可能会使您在应用程序启动和服务器响应之间保持一个竞争状态。

#3


0  

This is an old question, seems we have some chicken egg thing going on if we want to rely on the core capability of the library.

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

Instead of solving the problem in a fundamental way, what I did is by-pass. Create a directive that wraps the whole body. Ex.

我所做的不是用最基本的方法来解决问题,而是旁路。创建一个包装整个身体的指令。前女友。

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

Now mc-body needs to be initialized before rendering (once), ex.

现在需要在呈现(一次)之前初始化mc-body。

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

Auth is a service or provider, ex.

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

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

Seems to me that I do have control on the order of the bootstrap, it is after the regular bootstrap resolves all provider configuration and then try to initialize mc-body directive.

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

And this directive seems to me can be ahead of routing, because routing is also injected via a directive ex. <ui-route />. But I can be wrong on this. Needs some more investigation.

在我看来,这个指令似乎可以先于路由,因为路由也是通过一个指令ex. 注入的。但我可能是错的。需要更多的调查。

#4


-2  

In response to your question, "Any Ideas?", I would have respond with "yes". But wait, there's more!

在回答你的问题“有什么想法吗?”,我会回答“是”。别急,还有更多!

I suggest just using JQuery in the config. For example:

我建议在配置中使用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);
        }
    });
}]);

#1


154  

The bottom line is:

  • You CANNOT inject a service into the provider configuration section.
  • 不能将服务注入到provider configuration部分。
  • You CAN inject a service into the section which initializes the provider's service.
  • 可以将服务注入初始化提供者服务的部分。

Details:

Angular framework has a 2 phase initialization process:

角框架有两阶段初始化过程:

PHASE 1: Config

During the config phase all of the providers are initialized and all of the config sections are executed. The config sections may contain code which configures the provider objects and therefore they can be injected with provider objects. However, since the providers are the factories for the service objects and at this stage the providers are not fully initialized/configured -> you cannot ask the provider to create a service for you at this stage -> at the configuration stage you cannot use/inject services. When this phase is completed all of the providers are ready (no more provider configuration can be done after the configuration phase is completed).

在配置阶段中,所有的提供者都被初始化,所有的配置部分都被执行。配置部分可能包含配置提供程序对象的代码,因此可以将它们注入提供程序对象。但是,由于提供程序是服务对象的工厂,而且在此阶段,提供程序还没有完全初始化/配置——您不能要求提供程序在此阶段为您创建服务——在配置阶段不能使用/注入服务的>。当这个阶段完成时,所有的提供者都准备好了(在配置阶段完成后,不能再进行提供者配置)。

PHASE 2: Run

During run phase all the run sections are executed. At this stage the providers are ready and can create services -> during run phase you can use/inject services.

在运行阶段,将执行所有的运行部分。在这个阶段,提供程序已经准备好,可以在运行阶段创建服务——>,您可以使用/注入服务。

Examples:

1. Injecting the $http service to the provider initialization function WILL NOT work

//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;
    };
});

Since we are trying to inject the $http service into a function which is executed during the config phase we will get an error:

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

Uncaught Error: Unknown provider: $http from services 

What this error is actually saying is that the $httpProvider which is used to create the $http service is not ready yet (since we are still in the config phase).

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

2. Injecting the $http service to the service initialization function WILL work:

//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;
    };
});

Since we are now injecting the service into the service initialization function, which is executed during run phase this code will work.

由于我们现在将服务注入到服务初始化函数中,该函数在运行阶段执行,所以这段代码将有效。

#2


59  

This might give you a little leverage:

这可能会让你有一些优势:

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

But be careful, the success/error callbacks might keep you in a race-condition between the app start and the server response.

但是要小心,成功/错误回调可能会使您在应用程序启动和服务器响应之间保持一个竞争状态。

#3


0  

This is an old question, seems we have some chicken egg thing going on if we want to rely on the core capability of the library.

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

Instead of solving the problem in a fundamental way, what I did is by-pass. Create a directive that wraps the whole body. Ex.

我所做的不是用最基本的方法来解决问题,而是旁路。创建一个包装整个身体的指令。前女友。

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

Now mc-body needs to be initialized before rendering (once), ex.

现在需要在呈现(一次)之前初始化mc-body。

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

Auth is a service or provider, ex.

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

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

Seems to me that I do have control on the order of the bootstrap, it is after the regular bootstrap resolves all provider configuration and then try to initialize mc-body directive.

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

And this directive seems to me can be ahead of routing, because routing is also injected via a directive ex. <ui-route />. But I can be wrong on this. Needs some more investigation.

在我看来,这个指令似乎可以先于路由,因为路由也是通过一个指令ex. 注入的。但我可能是错的。需要更多的调查。

#4


-2  

In response to your question, "Any Ideas?", I would have respond with "yes". But wait, there's more!

在回答你的问题“有什么想法吗?”,我会回答“是”。别急,还有更多!

I suggest just using JQuery in the config. For example:

我建议在配置中使用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);
        }
    });
}]);