169

コントローラーが呼び出される前にデータを取得できるように、app.config にサービスを挿入したいと考えています。私はこのように試しました:

サービス:

app.service('dbService', function() {
    return {
        getData: function($q, $http) {
            var defer = $q.defer();
            $http.get('db.php/score/getData').success(function(data) {
                defer.resolve(data);            
            });
            return defer.promise;
        }
    };
});

構成:

app.config(function ($routeProvider, dbService) {
    $routeProvider
        .when('/',
        {
            templateUrl: "partials/editor.html",
            controller: "AppCtrl",
            resolve: {
                data: dbService.getData(),
            }
        })
});

しかし、私はこのエラーが発生します:

エラー: 不明なプロバイダー: EditorApp からの dbService

セットアップを修正してこのサービスを挿入する方法は?

4

10 に答える 10

131

アレックスは、あなたがやろうとしていることを実行できない正しい理由を提供したので、+1. ただし、解決策の設計方法を十分に使用していないため、この問題が発生しています。

resolveサービスの文字列または注入される値を返す関数のいずれかを取ります。後者を行っているため、実際の関数を渡す必要があります。

resolve: {
  data: function (dbService) {
    return dbService.getData();
  }
}

フレームワークが resolvedataになると、関数に が挿入dbServiceされるので、自由に使用できます。configこれを達成するために、ブロックに注入する必要はまったくありません。

ボナペティ!

于 2013-04-10T23:12:10.630 に答える
5

** angular.injector を使用して、他のモジュールから明示的にサービスをリクエストします **

kim3er's answerについて詳しく説明すると、他のモジュールに含まれている限り、プロバイダーに変更せずにサービス、工場などを提供できます...

ただし、*Providerangularがモジュールを遅延ロードするため、(サービスまたはファクトリを処理した後にangularによって内部的に作成される)が常に利用可能であるかどうかはわかりません(最初にロードされたものに依存する場合があります)。

値を再注入する場合は、定数として扱う必要があることに注意してください。

これは、より明示的で、おそらくより信頼性の高い方法です +動作中のプランカー

var base = angular.module('myAppBaseModule', [])
base.factory('Foo', function() { 
  console.log("Foo");
  var Foo = function(name) { this.name = name; };
  Foo.prototype.hello = function() {
    return "Hello from factory instance " + this.name;
  }
  return Foo;
})
base.service('serviceFoo', function() {
  this.hello = function() {
    return "Service says hello";
  }
  return this;
});

var app = angular.module('appModule', []);
app.config(function($provide) {
  var base = angular.injector(['myAppBaseModule']);
  $provide.constant('Foo', base.get('Foo'));
  $provide.constant('serviceFoo', base.get('serviceFoo'));
});
app.controller('appCtrl', function($scope, Foo, serviceFoo) {
  $scope.appHello = (new Foo("app")).hello();
  $scope.serviceHello = serviceFoo.hello();
});
于 2014-10-09T17:42:10.243 に答える
2

それを行うのは非常に簡単な解決策

: サービスは構成の実行時に初期化されないため、非同期呼び出し専用です。

メソッドを使用できますrun()。例 :

  1. あなたのサービスは「MyService」と呼ばれます
  2. プロバイダー「MyProvider」での非同期実行に使用したい

あなたのコード:

(function () { //To isolate code TO NEVER HAVE A GLOBAL VARIABLE!

    //Store your service into an internal variable
    //It's an internal variable because you have wrapped this code with a (function () { --- })();
    var theServiceToInject = null;

    //Declare your application
    var myApp = angular.module("MyApplication", []);

    //Set configuration
    myApp.config(['MyProvider', function (MyProvider) {
        MyProvider.callMyMethod(function () {
            theServiceToInject.methodOnService();
        });
    }]);

    //When application is initialized inject your service
    myApp.run(['MyService', function (MyService) {
        theServiceToInject = MyService;
    }]);
});
于 2015-05-07T10:15:39.423 に答える
2

$injector を使用して構成内のサービス メソッドを呼び出す

同様の問題があり、上記の $injector サービスを使用して解決しました。サービスを直接注入しようとしましたが、$http への循環依存になってしまいました。サービスはエラーのあるモーダルを表示し、$https にも依存する ui-bootstrap モーダルを使用しています。

    $httpProvider.interceptors.push(function($injector) {
    return {
        "responseError": function(response) {

            console.log("Error Response status: " + response.status);

            if (response.status === 0) {
                var myService= $injector.get("myService");
                myService.showError("An unexpected error occurred. Please refresh the page.")
            }
        }
    }
于 2015-01-04T17:34:31.453 に答える
1

うーん、これはちょっと苦労しましたが、実際にやってみました。

角度が変更されたために回答が古くなっているかどうかはわかりませんが、次の方法で行うことができます。

これはあなたのサービスです:

.factory('beerRetrievalService', function ($http, $q, $log) {
  return {
    getRandomBeer: function() {
      var deferred = $q.defer();
      var beer = {};

      $http.post('beer-detail', {})
      .then(function(response) {
        beer.beerDetail = response.data;
      },
      function(err) {
        $log.error('Error getting random beer', err);
        deferred.reject({});
      });

      return deferred.promise;
    }
  };
 });

そして、これが構成です

.when('/beer-detail', {
  templateUrl : '/beer-detail',
  controller  : 'productDetailController',

  resolve: {
    beer: function(beerRetrievalService) {
      return beerRetrievalService.getRandomBeer();
    }
  }
})
于 2015-09-21T21:05:09.283 に答える
0

最も簡単な方法: $injector = angular.element(document.body).injector()

次に、それを使用して実行するinvoke()か、get()

于 2015-07-04T19:00:29.487 に答える