web-dev-qa-db-ja.com

アプリの設定、angular.jsのカスタムプロバイダー内で$ httpを使用します

主な質問-それは可能ですか?私は運なしで試しました。

メインapp.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 

何か案は?

ありがとう!

90
Kosmetika

一番下の行は次のとおりです。

  • あなたできませんプロバイダー構成セクションにサービスを挿入します
  • YouCANプロバイダーのサービスを初期化するセクションにサービスを挿入できます

詳細:

Angularフレームワークには2段階の初期化プロセスがあります。

フェーズ1:構成

configフェーズでは、すべてのプロバイダーが初期化され、すべてのconfigセクションが実行されます。 configセクションには、プロバイダーオブジェクトを構成するコードが含まれている可能性があるため、プロバイダーオブジェクトを挿入できます。ただし、プロバイダーはサービスオブジェクトのファクトリであり、この段階ではプロバイダーは完全に初期化/構成されていません-> この段階でプロバイダーにサービスの作成を依頼することはできません->構成段階でサービスを使用/挿入することはできません。このフェーズが完了すると、すべてのプロバイダーの準備が整います(構成フェーズが完了した後、プロバイダーの構成を行うことはできません)。

フェーズ2:実行

runフェーズ中に、すべてのrunセクションが実行されます。この段階でプロバイダーは準備が整っており、サービスを作成できます->サービスを使用/挿入できるrunフェーズ中

例:

1. $httpサービスをプロバイダー初期化関数に挿入するWILL NOTwork

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

configフェーズ中に実行される関数に$httpサービスを挿入しようとしているため、エラーが発生します。

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フェーズで実行されるサービス初期化関数にサービスを注入しているため、このコードは機能します。

158
Dana Shalev

これにより、少し活用できます。

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

しかし、注意してください、成功/エラーコールバックは、アプリの起動とサーバーの応答の間の競合状態を維持する可能性があります。

63
Cody

これは古い質問です。ライブラリのコア機能に依存したい場合、鶏の卵のようなものが進行しているようです。

基本的な方法で問題を解決する代わりに、バイパスを行いました。本体全体をラップするディレクティブを作成します。例.

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

mc-bodyは、レンダリングの前に(1回)初期化する必要があります。

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

私はブートストラップの順序を制御しているように見えますが、それは通常のbootstrapがすべてのプロバイダー構成を解決してからmc-bodyディレクティブを初期化しようとした後です。

また、ルーティングはディレクティブexを介して注入されるため、このディレクティブはルーティングよりも先に進むことができます。 <ui-route />。しかし、私はこれについて間違っている可能性があります。さらに調査が必要です。

1
windmaomao