169 votes

Injecter le service dans app.config

Je veux un service d’injecter dans app.config, afin que les données peuvent être récupérées avant que le contrôleur soit appelé. J’ai essayé comme ceci :

Service :

Config :

Mais j’obtiens cette erreur :

Erreur : Fournisseur inconnu : mDBService de EditorApp

Comment faire pour corriger le programme d’installation et d’injecter ce service ?

140voto

Brian Vanderbusch Points 1405

Configurer votre service personnalisé AngularJS Fournisseur

En dépit de ce que l'on a Accepté la réponse dit, vous POUVEZ faire ce que vous avaient l'intention de le faire, mais vous devez le configurer en tant que configurable fournisseur, de sorte qu'il est disponible comme un service au cours de la phase de configuration.. d'Abord, changer votre Service auprès d'un fournisseur comme indiqué ci-dessous. La principale différence ici est qu'après le réglage de la valeur de defer, vous définissez l' defer.promise de la propriété de la promesse de l'objet renvoyé par $http.get:

Fournisseur de Service: (fournisseur de: service de la recette)

app.provider('dbService', function dbServiceProvider() {

  //the provider recipe for services require you specify a $get function
  this.$get= ['dbhost',function dbServiceFactory(dbhost){

     return new DbService(dbhost);  //return the factory as a provider, that is available during the configuration phase
  }]

});

  function DbService(dbhost){
      var status;
      this.setUrl = function(url){
          dbhost = url;
      }


      this.getData = function($http){
            return $http.get(dbhost+'db.php/score/getData')
                    .success(function(data){
                        //handle any special stuff here, I would suggest the following:
                        status = 'ok';
                        status.data = data;
                     })
                     .error(function(message){
                        status = 'error';
                        status.message = message;

                     })
                     .then(function(){
                         return status;  // now we return an object with data or information about error for special handling inside your application configuration
                      })
      }
  }

Maintenant, vous avez un configurable Fournisseur personnalisé, il vous suffit de l'injecter. Principale différence ici étant le manque de "Fournisseur sur votre injectable".

config:

app.config(function ($routeProvider) { 


    $routeProvider
        .when('/',
        {
            templateUrl: "partials/editor.html",
            controller: "AppCtrl",
          resolve: {
              dbData: function(DbService, $http){
                 /*
                 *dbServiceProvider returns a dbService instance to your app whenever
                 * needed, and this instance is setup internally with a promise, 
                 * so you don't need to worry about $q and all that
                 */
                 return DbService('http://dbhost.com').getData();
              }
          }
        })
});

utilisation résolu de données dans votre appCtrl

app.controller('appCtrl',function(dbData, DbService){
     $scope.dbData = dbData;

     //you can also create and use another instance of the dbService here...
     // to do whatever you programmed it to do, by adding functions inside the constructor
     // DbService(), the following assumes you added a rmUser(userObj) function in the factory
     $scope.removeDbUser = function(user){
         DbService.rmUser(user);
     }

})

Alternatives Possibles

L'alternative suivante est une approche similaire, mais permet de définir à l'intérieur de l' .config, en encapsulant le service à l'intérieur du module spécifique dans le contexte de votre application. Choisissez la méthode qui vous convient. Voir aussi ci-dessous des notes sur une 3ème alternative et liens utiles pour vous aider à obtenir le blocage de toutes ces choses

app.config(function($routeProvider, $provide){
  $provide.service('dbService',function(){})//set up your service inside the module's config.

  $routeProvider
        .when('/',
        {
            templateUrl: "partials/editor.html",
            controller: "AppCtrl",
            resolve: {
                data: 
                }
            }
        })


});

Quelques Ressources utiles

  • Jean-Lindquist a un super 5 minutes d'explication et de démonstration de ce à tête d'oeuf.io, et c'est l'une des leçons gratuites! En gros, j'ai modifié sa démonstration en la rendant $http spécifiques dans le contexte de la présente demande
  • Consulter le guide du Développeur AngularJS sur les Fournisseurs de
  • Il est également une excellente explication à propos de factory/service/provider à clevertech.biz.

Le fournisseur vous donne un peu plus de configuration sur l' .service méthode, ce qui la rend plus comme une application fournisseur de niveau, mais vous pouvez également saisir cette dans la config de l'objet lui-même par l'injection d' $provide en config comme ceci:

131voto

Josh David Miller Points 66508

Alex fourni le bon motif pour ne pas être en mesure de faire ce que vous êtes en train de faire, donc +1. Mais vous rencontrez ce problème, parce que vous n'êtes pas tout à fait à l'aide résout façon dont ils sont conçus.

resolve prend soit la chaîne de caractères d'un service ou d'une fonction retournant une valeur à être injecté. Puisque vous êtes en train de faire le dernier, vous devez passer dans une fonction réelle:

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

Une fois que le cadre va à résoudre data, il va injecter de l' dbService dans la fonction de sorte que vous pouvez l'utiliser librement. Vous n'avez pas besoin d'injecter dans l' config bloc à tout pour accomplir cette tâche.

Bon appétit!

21voto

Alex Osborn Points 2756

Réponse courte: vous ne pouvez pas. AngularJS ne vous permettra pas d'injecter des services dans la config, car il ne peut pas être sûr qu'ils ont été correctement chargé.

Voir cette question et la réponse: AngularJS l'injection de dépendance de la valeur à l'intérieur du module.config

Un module est un ensemble de configuration et d'exécution des blocs qui se appliquée à la demande pendant le processus d'amorçage. Dans son forme la plus simple, le module se composent de collecte de deux types de blocs:

Des blocs de Configuration - exécuté pendant le fournisseur d'enregistrements et de la phase de configuration. Seuls les prestataires et les constantes peut être injecté dans des blocs de configuration. C'est pour éviter d' accidentelle de l'instanciation de services avant qu'ils ont été entièrement configuré.

5voto

kim3er Points 3354

Je ne pense pas que vous êtes censé pour être capable de faire cela, mais j’ai injecté avec succès un service dans un `` bloc. (AngularJS v1.0.7)

5voto

00500005 Points 100

Explicitement la demande de services à d'autres modules à l'aide de anuglar.injecteur

Juste pour préciser kim3er de réponse, vous pouvez fournir des services, des usines, etc ... sans changer de fournisseurs, tant qu'ils sont inclus dans les autres modules.

Cependant, je ne suis pas sûr si l' *Provider (qui est fait en interne par angulaire après qu'il traite d'un service, ou à l'usine) sera toujours disponible (il peut dépendre d'autre chargé en premier), angulaire paresseusement charge des modules.

Notez que si vous souhaitez ré-injecter les valeurs qu'ils devraient être traités comme des constantes

Voici de manière plus explicite, et probablement plus fiable façon de le faire + un travail plunker

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X