angularjs - provider vs service



AngularJS: Service vs fournisseur vs usine (20)

Quelles sont les différences entre un Service , un Provider et une Factory dans AngularJS?

https://code.i-harness.com


JS Fiddle Demo

Exemple "Hello world" avec factory / service / provider :

var myApp = angular.module('myApp', []);

//service style, probably the simplest one
myApp.service('helloWorldFromService', function() {
    this.sayHello = function() {
        return "Hello, World!";
    };
});

//factory style, more involved but more sophisticated
myApp.factory('helloWorldFromFactory', function() {
    return {
        sayHello: function() {
            return "Hello, World!";
        }
    };
});
    
//provider style, full blown, configurable version     
myApp.provider('helloWorld', function() {

    this.name = 'Default';

    this.$get = function() {
        var name = this.name;
        return {
            sayHello: function() {
                return "Hello, " + name + "!";
            }
        }
    };

    this.setName = function(name) {
        this.name = name;
    };
});

//hey, we can configure a provider!            
myApp.config(function(helloWorldProvider){
    helloWorldProvider.setName('World');
});
        

function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) {
    
    $scope.hellos = [
        helloWorld.sayHello(),
        helloWorldFromFactory.sayHello(),
        helloWorldFromService.sayHello()];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="MyCtrl">
    {{hellos}}
</div>
</body>


Usine

Vous donnez une fonction à AngularJS, AngularJS mettra en cache et injectera la valeur de retour lorsque la fabrique est demandée.

Exemple:

app.factory('factory', function() {
    var name = '';
    // Return value **is** the object that will be injected
    return {
        name: name;
    }
})

Usage:

app.controller('ctrl', function($scope, factory) {
     $scope.name = factory.name;
});

Un service

Vous donnez une fonction à AngularJS, AngularJS appellera new pour l’instancier. C'est l'instance créée par AngularJS qui sera mise en cache et injectée à la demande du service. Puisque new a été utilisé pour instancier le service, le mot - clé this est valide et désigne l'instance.

Exemple:

app.service('service', function() {
     var name = '';
     this.setName = function(newName) {
         name = newName;
     }
     this.getName = function() {
         return name;
     }
});

Usage:

app.controller('ctrl', function($scope, service) {
   $scope.name = service.getName();
});

Fournisseur

Vous donnez une fonction à AngularJS, et AngularJS appellera cette $getfonction. C'est la valeur de retour de la $getfonction qui sera mise en cache et injectée lorsque le service sera demandé.

Les fournisseurs vous permettent de configurer le fournisseur avant que AngularJS appelle la $getméthode pour obtenir le produit injectable.

Exemple:

app.provider('provider', function() {
     var name = '';
     this.setName = function(newName) {
          name = newName;
     }
     this.$get = function() {
         return {
            name: name
         }
     }
})

Utilisation (comme injectable dans un contrôleur)

app.controller('ctrl', function($scope, provider) {
    $scope.name = provider.name;
});

Utilisation (la configuration du fournisseur avant $getest appelée pour créer l'injectable)

app.config(function(providerProvider) {
    providerProvider.setName('John');
});

Tous les services sont des singletons ; ils sont instanciés une fois par application. Ils peuvent être de n'importe quel type , qu'il s'agisse d'une primitive, d'un littéral d'objet, d'une fonction ou même d'une instance d'un type personnalisé.

Les méthodes value , factory , service , constant et provider sont toutes des fournisseurs. Ils enseignent à l'injecteur comment instancier les services.

Le plus détaillé, mais aussi le plus complet, est une recette de fournisseur. Les quatre types de recettes restants - Valeur, Usine, Service et Constante - ne sont que du sucre syntaxique en plus d'une recette du fournisseur .

  • La recette de valeur est le cas le plus simple, dans lequel vous instanciez vous-même le service et fournissez la valeur instanciée à l'injecteur.
  • La recette Usine donne à l'injecteur une fonction usine qu'il appelle lorsqu'il doit instancier le service. Lorsqu'elle est appelée, la fonction fabrique crée et renvoie l'instance de service. Les dépendances du service sont injectées en tant qu'arguments des fonctions. Donc, en utilisant cette recette ajoute les capacités suivantes:
    • Possibilité d'utiliser d'autres services (avoir des dépendances)
    • Initialisation du service
    • Initialisation différée / lente
  • La recette de service est presque identique à la recette Usine, mais ici l’injecteur appelle un constructeur avec le nouvel opérateur au lieu d’une fonction usine.
  • La recette du fournisseur est généralement excessive . Il ajoute une couche d'indirection supplémentaire en vous permettant de configurer la création de la fabrique.

    Vous devez utiliser la recette du fournisseur uniquement lorsque vous souhaitez exposer une API pour une configuration à l'échelle de l'application à effectuer avant le démarrage de l'application. Cela n’est généralement intéressant que pour les services réutilisables dont le comportement peut varier légèrement d’une application à l’autre.

  • La recette Constante est semblable à la recette Valeur, sauf qu'elle vous permet de définir les services disponibles dans la phase de configuration . Plus tôt que les services créés à l'aide de la recette Valeur. Contrairement aux valeurs, elles ne peuvent pas être décorées à l'aide d'un decorator .
Voir la documentation du fournisseur .


Comprendre l'usine, le service et le fournisseur AngularJS

Tous ces éléments sont utilisés pour partager des objets singleton réutilisables. Il est utile de partager du code réutilisable sur votre application / divers composants / modules.

De Docs Service/Factory :

  • Instancié en différé - Angular instancie uniquement un service / une usine lorsqu'un composant d'application en dépend.
  • Singletons - Chaque composant dépendant d'un service obtient une référence à l'instance unique générée par la fabrique de services.

Usine

Une fabrique est une fonction dans laquelle vous pouvez manipuler / ajouter une logique avant de créer un objet, puis l'objet nouvellement créé est renvoyé.

app.factory('MyFactory', function() {
    var serviceObj = {};
    //creating an object with methods/functions or variables
    serviceObj.myFunction = function() {
        //TO DO:
    };
    //return that object
    return serviceObj;
});

Usage

Ce peut être juste un ensemble de fonctions comme une classe. Par conséquent, il peut être instancié dans différents contrôleurs lorsque vous l'injectez dans vos fonctions contrôleur / usine / directive. Il n'est instancié qu'une fois par application.

Un service

Tout en regardant les services, pensez au prototype de tableau. Un service est une fonction qui instancie un nouvel objet à l'aide du mot clé "new". Vous pouvez ajouter des propriétés et des fonctions à un objet de service à l'aide du thismot clé. Contrairement à une fabrique, il ne renvoie rien (il retourne un objet contenant des méthodes / propriétés).

app.service('MyService', function() {
    //directly binding events to this context
    this.myServiceFunction = function() {
        //TO DO:
    };
});

Usage

Utilisez-le lorsque vous devez partager un seul objet dans toute l'application. Par exemple, informations d'utilisateur authentifiées, méthodes / données partageables, fonctions utilitaires, etc.

Fournisseur

Un fournisseur est utilisé pour créer un objet de service configurable. Vous pouvez configurer le paramètre de service à partir de la fonction de configuration. Il retourne une valeur en utilisant la $get()fonction. La $getfonction est exécutée lors de la phase d'exécution en mode angulaire.

app.provider('configurableService', function() {
    var name = '';
    //this method can be be available at configuration time inside app.config.
    this.setName = function(newName) {
        name = newName;
    };
    this.$get = function() {
        var getName = function() {
             return name;
        };
        return {
            getName: getName //exposed object to where it gets injected.
        };
    };
});

Usage

Lorsque vous devez fournir une configuration par module pour votre objet de service avant de le rendre disponible, par exemple. supposons que vous souhaitiez définir votre URL API en fonction de votre environnement dev, stageouprod

REMARQUE

Seul le fournisseur sera disponible dans la phase de configuration angulaire, alors que le service et l’usine ne le sont pas.

J'espère que cela a éclairci votre compréhension de Factory, Service and Provider .


Service vs fournisseur vs usine:

J'essaie de garder les choses simples. Tout repose sur le concept JavaScript de base.

Tout d’abord, parlons des services dans AngularJS!

Qu'est-ce que le service? Dans AngularJS, Servicen’est rien qu’un objet JavaScript unique qui peut stocker des méthodes ou des propriétés utiles. Cet objet singleton est créé par ngApp (application angulaire) et il est partagé entre tous les contrôleurs de l'application actuelle. Lorsque Angularjs instancie un objet de service, il enregistre cet objet de service avec un nom de service unique. Ainsi, chaque fois que nous avons besoin d’une instance de service, Angular recherche dans le registre ce nom de service et renvoie la référence à l’objet service. De telle sorte que nous puissions appeler une méthode, des propriétés d'accès, etc. sur l'objet de service. Vous vous demandez peut-être si vous pouvez également mettre des propriétés, des méthodes sur l'objet scope des contrôleurs! Alors pourquoi avez-vous besoin d'un objet de service? Answers is: les services sont partagés par plusieurs contrôleurs. Si vous mettez des propriétés / méthodes dans l'objet scope d'un contrôleur, il ne sera disponible que pour l'étendue actuelle.Mais lorsque vous définissez des méthodes, des propriétés sur un objet de service, celui-ci sera disponible de manière globale et sera accessible dans l'étendue de tout contrôleur en injectant ce service.

Ainsi, s’il ya trois contrôleurs, qu’il s’agisse de controllerA, controllerB et controllerC, tous partageront la même instance de service.

<div ng-controller='controllerA'>
    <!-- controllerA scope -->
</div>
<div ng-controller='controllerB'>
    <!-- controllerB scope -->
</div>
<div ng-controller='controllerC'>
    <!-- controllerC scope -->
</div>

Comment créer un service?

AngularJS propose différentes méthodes pour enregistrer un service. Ici, nous allons nous concentrer sur trois méthodes usine (..), service (..), fournisseur (..);

Utilisez ce lien pour la référence de code

Fonction d'usine:

Nous pouvons définir une fonction d'usine comme ci-dessous.

factory('serviceName',function fnFactory(){ return serviceInstance;})

AngularJS fournit la méthode 'factory (' serviceName ', fnFactory)' qui prend deux paramètres, serviceName et une fonction JavaScript. Angular crée une instance de service en appelant la fonction fnFactory () comme ci-dessous.

var serviceInstace = fnFactory();

La fonction transmise peut définir un objet et le renvoyer. AngularJS stocke simplement cette référence d'objet à une variable qui est passée en premier argument. Tout ce qui est renvoyé par fnFactory sera lié à serviceInstance. Au lieu de renvoyer un objet, nous pouvons également renvoyer une fonction, des valeurs, etc. Tout ce que nous retournerons sera disponible pour l'instance de service.

Exemple:

var app= angular.module('myApp', []);
//creating service using factory method
app.factory('factoryPattern',function(){
  var data={
    'firstName':'Tom',
    'lastName':' Cruise',
    greet: function(){
      console.log('hello!' + this.firstName + this.lastName);
    }
  };

  //Now all the properties and methods of data object will be available in our service object
  return data;
});

Fonction de service:

service('serviceName',function fnServiceConstructor(){})

C'est l'inverse, nous pouvons enregistrer un service. La seule différence réside dans la manière dont AngularJS tente d'instancier l'objet de service. Cette fois, angular utilise le mot-clé 'new' et appelle la fonction constructeur de la manière suivante.

var serviceInstance = new fnServiceConstructor();

Dans la fonction constructeur, nous pouvons utiliser le mot clé 'this' pour ajouter des propriétés / méthodes à l'objet de service. Exemple:

//Creating a service using the service method
var app= angular.module('myApp', []);
app.service('servicePattern',function(){
  this.firstName ='James';
  this.lastName =' Bond';
  this.greet = function(){
    console.log('My Name is '+ this.firstName + this.lastName);
  };
});

Fonction du fournisseur:

La fonction Provider () est un autre moyen de créer des services. Laissons-nous nous intéresser à la création d’un service qui n’affiche que des messages de bienvenue à l’utilisateur. Mais nous souhaitons également fournir une fonctionnalité permettant à l’utilisateur de définir son propre message de bienvenue. En termes techniques, nous voulons créer des services configurables. Comment peut-on le faire ? Il doit y avoir un moyen, pour que l'application puisse transmettre leurs messages d'accueil personnalisés et qu'Angularjs le rende disponible pour la fonction fabrique / constructeur qui crée notre instance de services. Dans un tel cas, la fonction provider () fait le travail. En utilisant la fonction provider (), nous pouvons créer des services configurables.

Nous pouvons créer des services configurables en utilisant la syntaxe de fournisseur indiquée ci-dessous.

/*step1:define a service */
app.provider('service',function serviceProviderConstructor(){});

/*step2:configure the service */
app.config(function configureService(serviceProvider){});

Comment la syntaxe du fournisseur fonctionne-t-elle en interne?

L'objet 1.Provider est créé à l'aide de la fonction constructeur définie dans notre fonction fournisseur.

var serviceProvider = new serviceProviderConstructor();

2.La fonction que nous avons passée dans app.config () est exécutée. C'est ce qu'on appelle la phase de configuration, et nous avons ici la possibilité de personnaliser notre service.

configureService(serviceProvider);

3.Enfin, l'instance de service est créée en appelant la méthode $ get de serviceProvider.

serviceInstance = serviceProvider.$get()

Exemple de code pour la création de service à l'aide de la syntaxe:

var app= angular.module('myApp', []);
app.provider('providerPattern',function providerConstructor(){
  //this function works as constructor function for provider
  this.firstName = 'Arnold ';
  this.lastName = ' Schwarzenegger' ;
  this.greetMessage = ' Welcome, This is default Greeting Message' ;
  //adding some method which we can call in app.config() function
  this.setGreetMsg = function(msg){
    if(msg){
      this.greetMessage =  msg ;
    }
  };

  //We can also add a method which can change firstName and lastName
  this.$get = function(){
    var firstName = this.firstName;
    var lastName = this.lastName ;
    var greetMessage = this.greetMessage;
    var data={
       greet: function(){
         console.log('hello, ' + firstName + lastName+'! '+ greetMessage);
       }
    };
    return data ;
  };
});

app.config(
  function(providerPatternProvider){
    providerPatternProvider.setGreetMsg(' How do you do ?');
  }
);

Démo de travail

Résumé:

Factory utilise une fonction factory qui renvoie une instance de service. serviceInstance = fnFactory ();

Le service utilise une fonction constructeur et Angular appelle cette fonction constructeur à l'aide du mot clé "new" pour créer l'instance de service. serviceInstance = new fnServiceConstructor ();

Fournisseur définit une fonction fournisseurConstructeur, cette fonction fournisseurConstructeur définit une fonction d'usine $ get . Appels angulaires $ get () pour créer l'objet de service. La syntaxe de fournisseur présente l'avantage supplémentaire de configurer l'objet de service avant qu'il ne soit instancié. serviceInstance = $ get ();


TL; DR

1) Lorsque vous utilisez une fabrique, vous créez un objet, lui ajoutez des propriétés, puis vous retournez ce même objet. Lorsque vous transmettez cette fabrique à votre contrôleur, les propriétés de l'objet sont désormais disponibles dans ce contrôleur via votre fabrique.

app.controller(‘myFactoryCtrl’, function($scope, myFactory){
  $scope.artist = myFactory.getArtist();
});

app.factory(‘myFactory’, function(){
  var _artist = ‘Shakira’;
  var service = {};

  service.getArtist = function(){
    return _artist;
  }

  return service;
});


2) Lorsque vous utilisez Service , AngularJS l’instancie en coulisse avec le mot-clé "new". A cause de cela, vous ajouterez des propriétés à 'this' et le service renverra 'this'. Lorsque vous transmettez le service à votre contrôleur, les propriétés de "ceci" seront désormais disponibles sur ce contrôleur via votre service.

app.controller(‘myServiceCtrl’, function($scope, myService){
  $scope.artist = myService.getArtist();
});

app.service(‘myService’, function(){
  var _artist = ‘Nelly’;
  this.getArtist = function(){
    return _artist;
  }
});



3) Les fournisseurs sont le seul service que vous pouvez transmettre à votre fonction .config (). Utilisez un fournisseur lorsque vous souhaitez fournir une configuration à l'échelle du module pour votre objet de service avant de le rendre disponible.

app.controller(‘myProvider’, function($scope, myProvider){
  $scope.artist = myProvider.getArtist();
  $scope.data.thingFromConfig = myProvider.thingOnConfig;
});

app.provider(‘myProvider’, function(){
 //Only the next two lines are available in the app.config()
 this._artist = ‘’;
 this.thingFromConfig = ‘’;
  this.$get = function(){
    var that = this;
    return {
      getArtist: function(){
        return that._artist;
      },
      thingOnConfig: that.thingFromConfig
    }
  }
});

app.config(function(myProviderProvider){
  myProviderProvider.thingFromConfig = ‘This was set in config’;
});



Non TL; DR

1) usine
Les usines constituent le moyen le plus populaire de créer et de configurer un service. Il n'y a vraiment pas beaucoup plus que ce que dit le TL; DR. Vous créez simplement un objet, lui ajoutez des propriétés, puis vous retournez ce même objet. Ensuite, lorsque vous transmettez la fabrique à votre contrôleur, les propriétés de l'objet sont désormais disponibles dans ce contrôleur via votre fabrique. Un exemple plus complet est ci-dessous.

app.factory(‘myFactory’, function(){
  var service = {};
  return service;
});

Maintenant, toutes les propriétés que nous attachons à 'service' seront disponibles lorsque nous transmettrons 'myFactory' à notre contrôleur.

Ajoutons maintenant des variables "privées" à notre fonction de rappel. Celles-ci ne seront pas directement accessibles à partir du contrôleur, mais nous finirons par configurer des méthodes getter / setter sur 'service' afin de pouvoir modifier ces variables 'privées' si nécessaire.

app.factory(‘myFactory’, function($http, $q){
  var service = {};
  var baseUrl = ‘https://itunes.apple.com/search?term=’;
  var _artist = ‘’;
  var _finalUrl = ‘’;

  var makeUrl = function(){
   _artist = _artist.split(‘ ‘).join(‘+’);
    _finalUrl = baseUrl + _artist + ‘&callback=JSON_CALLBACK’;
    return _finalUrl
  }

  return service;
});

Ici, vous remarquerez que nous n'attachons pas ces variables / fonctions à 'service'. Nous les créons simplement pour pouvoir les utiliser ou les modifier plus tard.

  • baseUrl est l'URL de base requise par l'API iTunes
  • _artist est l'artiste que nous souhaitons rechercher
  • _finalUrl est l'URL finale et entièrement construite vers laquelle nous allons appeler iTunes.
  • makeUrl est une fonction qui crée et renvoie notre URL conviviale pour iTunes.

Maintenant que nos variables et fonctions d'assistance / privées sont en place, ajoutons quelques propriétés à l'objet 'service'. Tout ce que nous mettons en "service" peut être utilisé directement dans n'importe quel contrôleur dans lequel nous transmettons "myFactory".

Nous allons créer les méthodes setArtist et getArtist qui renvoient ou définissent simplement l'artiste. Nous allons également créer une méthode qui appellera l'API iTunes avec notre URL créée. Cette méthode va renvoyer une promesse qui sera remplie une fois que les données seront revenues de l'API iTunes. Si vous n'avez pas beaucoup d'expérience dans l'utilisation des promesses dans AngularJS, je vous recommande vivement de les approfondir.

SetArtist accepte un artiste et vous permet de le définir. getArtist renvoie l'artiste. callItunes appelle d'abord makeUrl () afin de construire l'URL que nous utiliserons avec notre requête $ http. Ensuite, il configure un objet de promesse, fait une requête $ http avec notre URL finale, puis, puisque $ http renvoie une promesse, nous pouvons appeler .success ou .error après notre requête. Nous résolvons ensuite notre promesse avec les données iTunes ou nous la rejetons avec un message disant «Il y avait une erreur».

app.factory('myFactory', function($http, $q){
  var service = {};
  var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  var makeUrl = function(){
    _artist = _artist.split(' ').join('+');
    _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
    return _finalUrl;
  }

  service.setArtist = function(artist){
    _artist = artist;
  }

  service.getArtist = function(){
    return _artist;
  }

  service.callItunes = function(){
    makeUrl();
    var deferred = $q.defer();
    $http({
      method: 'JSONP',
      url: _finalUrl
    }).success(function(data){
      deferred.resolve(data);
    }).error(function(){
      deferred.reject('There was an error')
    })
    return deferred.promise;
  }

  return service;
});

Maintenant, notre usine est terminée. Nous pouvons maintenant injecter «myFactory» dans n’importe quel contrôleur et nous pourrons ensuite appeler nos méthodes que nous avons attachées à notre objet service (setArtist, getArtist et callItunes).

app.controller('myFactoryCtrl', function($scope, myFactory){
  $scope.data = {};
  $scope.updateArtist = function(){
    myFactory.setArtist($scope.data.artist);
  };

  $scope.submitArtist = function(){
    myFactory.callItunes()
      .then(function(data){
        $scope.data.artistData = data;
      }, function(data){
        alert(data);
      })
  }
});

Dans le contrôleur ci-dessus, nous injectons le service «myFactory». Nous définissons ensuite les propriétés de notre objet $ scope avec les données de 'myFactory'. Le seul code difficile ci-dessus est si vous n'avez jamais traité de promesses auparavant. Puisque callItunes renvoie une promesse, nous pouvons utiliser la méthode .then () et définir uniquement $ scope.data.artistData une fois que notre promesse est remplie avec les données iTunes. Vous remarquerez que notre contrôleur est très "mince" (c'est une bonne pratique de codage). Toutes nos données logiques et persistantes se trouvent dans notre service, pas dans notre contrôleur.

2) service
Peut-être que la chose la plus importante à savoir lors de la création d'un service est qu'il est instancié avec le mot-clé 'new'. Pour vous, gourous JavaScript, cela devrait vous donner un indice important sur la nature du code. Pour ceux d'entre vous qui ont une connaissance limitée de JavaScript ou pour ceux qui ne connaissent pas bien le «nouveau» mot clé, examinons quelques principes fondamentaux de JavaScript qui nous aideront éventuellement à comprendre la nature d'un service.

Pour vraiment voir les changements qui surviennent lorsque vous appelez une fonction avec le mot clé 'new', créons une fonction et appelez-la avec le mot clé 'new', puis montrons ce que l'interprète fait lorsqu'il voit le mot clé 'new'. Les résultats finaux seront les mêmes.

Commençons par créer notre constructeur.

var Person = function(name, age){
  this.name = name;
  this.age = age;
}

C'est une fonction constructeur typique de JavaScript. Désormais, chaque fois que nous appelons la fonction Person à l'aide du mot clé "new", "this" sera lié au nouvel objet créé.

Ajoutons maintenant une méthode sur le prototype de notre personne afin qu’elle soit disponible sur chaque instance de notre classe «personne».

Person.prototype.sayName = function(){
  alert(‘My name is ‘ + this.name);
}

Maintenant, comme nous mettons la fonction sayName sur le prototype, chaque instance de Person pourra appeler la fonction sayName afin d’alerter le nom de cette instance.

Maintenant que nous avons notre fonction constructeur Person et notre fonction sayName sur son prototype, créons en fait une instance de Person puis appelons la fonction sayName.

var tyler = new Person(‘Tyler’, 23);
tyler.sayName(); //alerts ‘My name is Tyler’

En résumé, le code permettant de créer un constructeur Person, d’ajouter une fonction à son prototype, de créer une instance Person, puis d’appeler la fonction sur son prototype ressemble à ceci.

var Person = function(name, age){
  this.name = name;
  this.age = age;
}
Person.prototype.sayName = function(){
  alert(‘My name is ‘ + this.name);
}
var tyler = new Person(‘Tyler’, 23);
tyler.sayName(); //alerts ‘My name is Tyler’

Examinons maintenant ce qui se passe réellement lorsque vous utilisez le mot-clé "nouveau" en JavaScript. La première chose que vous devriez remarquer est qu'après avoir utilisé "new" dans notre exemple, nous pouvons appeler une méthode (sayName) sur "tyler" comme s'il s'agissait d'un objet - c'est parce que c'est le cas. Donc, d’abord, nous savons que notre constructeur Person renvoie un objet, que nous le voyions ou non dans le code. Deuxièmement, nous savons que, puisque notre fonction sayName est située sur le prototype et non directement sur l'instance de personne, l'objet renvoyé par la fonction Person doit être délégué à son prototype lors de recherches en échec. En termes plus simples, lorsque nous appelons tyler.sayName (), l'interprète dit «OK, je vais regarder sur l'objet 'tyler» que nous venons de créer, localisez la fonction sayName, puis appelez-le. Attendez une minute, je ne le vois pas ici - je ne vois que le nom et l'âge, laissez-moi vérifier le prototype. Oui, on dirait que c'est sur le prototype, laissez-moi l'appeler. ”.

Vous trouverez ci-dessous un code indiquant comment vous pouvez penser à ce que le "nouveau" mot-clé fait réellement en JavaScript. C'est fondamentalement un exemple de code du paragraphe ci-dessus. J'ai mis la "vue interprète" ou la façon dont l'interprète voit le code à l'intérieur des notes.

var Person = function(name, age){
  //The below line creates an object(obj) that will delegate to the person’s prototype on failed lookups.
  //var obj = Object.create(Person.prototype);

  //The line directly below this sets ‘this’ to the newly created object
  //this = obj;

  this.name = name;
  this.age = age;

  //return this;
}

Maintenant que vous avez cette connaissance de ce que le "nouveau" mot-clé fait vraiment en JavaScript, la création d'un service dans AngularJS devrait être plus facile à comprendre.

La chose la plus importante à comprendre lors de la création d'un service est de savoir que les services sont instanciés avec le mot-clé 'nouveau' En combinant ces connaissances avec nos exemples ci-dessus, vous devez maintenant reconnaître que vous allez associer directement vos propriétés et méthodes à "this", qui seront ensuite renvoyées par le service lui-même. Jetons un coup d'oeil à ceci en action.

Contrairement à ce que nous avons fait à l’origine avec l’exemple Factory, nous n’avons pas besoin de créer un objet, mais de le renvoyer, car, comme cela a déjà été mentionné à maintes reprises, nous avons utilisé le mot clé 'new' pour que l’interprète crée cet objet et le délègue à c'est un prototype, puis retournez-le nous sans que nous ayons à faire le travail.

Tout d’abord, créons notre fonction «privée» et d’aide. Cela devrait sembler très familier puisque nous avons fait exactement la même chose avec notre usine. Je ne vais pas expliquer ce que chaque ligne fait ici car je l'ai fait dans l'exemple d'usine. Si vous êtes confus, relisez l'exemple d'usine.

app.service('myService', function($http, $q){
  var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  var makeUrl = function(){
    _artist = _artist.split(' ').join('+');
    _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
    return _finalUrl;
  }
});

Maintenant, nous allons attacher toutes les méthodes qui seront disponibles dans notre contrôleur à 'ceci'.

app.service('myService', function($http, $q){
  var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  var makeUrl = function(){
    _artist = _artist.split(' ').join('+');
    _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
    return _finalUrl;
  }

  this.setArtist = function(artist){
    _artist = artist;
  }

  this.getArtist = function(){
    return _artist;
  }

  this.callItunes = function(){
    makeUrl();
    var deferred = $q.defer();
    $http({
      method: 'JSONP',
      url: _finalUrl
    }).success(function(data){
      deferred.resolve(data);
    }).error(function(){
      deferred.reject('There was an error')
    })
    return deferred.promise;
  }

});

Maintenant, comme dans notre usine, setArtist, getArtist et callItunes seront disponibles dans le contrôleur par lequel nous passerons à myService. Voici le contrôleur myService (qui est presque identique à notre contrôleur d’usine).

app.controller('myServiceCtrl', function($scope, myService){
  $scope.data = {};
  $scope.updateArtist = function(){
    myService.setArtist($scope.data.artist);
  };

  $scope.submitArtist = function(){
    myService.callItunes()
      .then(function(data){
        $scope.data.artistData = data;
      }, function(data){
        alert(data);
      })
  }
});

Comme je l'ai déjà mentionné, une fois que vous comprenez vraiment ce que fait le «nouveau», les services sont presque identiques aux usines AngularJS.

3) fournisseur

La chose la plus importante à retenir sur les fournisseurs est qu’ils sont le seul service que vous pouvez transférer dans la partie app.config de votre application. Cela revêt une importance capitale si vous devez modifier une partie de votre objet de service avant qu'il ne soit disponible partout ailleurs dans votre application. Bien que très similaires aux services / usines, il y a quelques différences dont nous discuterons.

Nous avons d’abord configuré notre fournisseur de la même manière que nous l’avons fait avec notre service et notre usine. Les variables ci-dessous sont notre fonction "privée" et d'assistance.

app.provider('myProvider', function(){
   var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  //Going to set this property on the config function below.
  this.thingFromConfig = ‘’;

  var makeUrl = function(){
    _artist = _artist.split(' ').join('+');
    _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
    return _finalUrl;
  }
}

* Encore une fois, si une partie du code ci-dessus est source de confusion, consultez la section Usine où j'explique ce que tout cela fait plus de détails.

Vous pouvez imaginer que les fournisseurs ont trois sections. La première section contient les variables / fonctions «privées» qui seront modifiées / définies ultérieurement (voir ci-dessus). La deuxième section contient les variables / fonctions qui seront disponibles dans votre fonction app.config et sont donc disponibles pour être modifiées avant d’être disponibles ailleurs (voir également ci-dessus). Il est important de noter que ces variables doivent être attachées au mot clé 'this'. Dans notre exemple, seul 'thingFromConfig' sera disponible pour être modifié dans le fichier app.config. La troisième section (illustrée ci-dessous) regroupe toutes les variables / fonctions qui seront disponibles dans votre contrôleur lorsque vous transmettez le service «myProvider» à ce contrôleur spécifique.

Lors de la création d'un service avec Fournisseur, les seules propriétés / méthodes disponibles dans votre contrôleur sont les propriétés / méthodes renvoyées par la fonction $ get (). Le code ci-dessous met $ get sur 'this' (qui, nous le savons, sera finalement renvoyé par cette fonction). Maintenant, cette fonction $ get renvoie toutes les méthodes / propriétés que nous voulons être disponibles dans le contrôleur. Voici un exemple de code.

this.$get = function($http, $q){
    return {
      callItunes: function(){
        makeUrl();
        var deferred = $q.defer();
        $http({
          method: 'JSONP',
          url: _finalUrl
        }).success(function(data){
          deferred.resolve(data);
        }).error(function(){
          deferred.reject('There was an error')
        })
        return deferred.promise;
      },
      setArtist: function(artist){
        _artist = artist;
      },
      getArtist: function(){
        return _artist;
      },
      thingOnConfig: this.thingFromConfig
    }
  }

Maintenant, le code complet du fournisseur ressemble à ceci

app.provider('myProvider', function(){
  var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  //Going to set this property on the config function below
  this.thingFromConfig = '';

  var makeUrl = function(){
    _artist = _artist.split(' ').join('+');
    _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
    return _finalUrl;
  }

  this.$get = function($http, $q){
    return {
      callItunes: function(){
        makeUrl();
        var deferred = $q.defer();
        $http({
          method: 'JSONP',
          url: _finalUrl
        }).success(function(data){
          deferred.resolve(data);
        }).error(function(){
          deferred.reject('There was an error')
        })
        return deferred.promise;
      },
      setArtist: function(artist){
        _artist = artist;
      },
      getArtist: function(){
        return _artist;
      },
      thingOnConfig: this.thingFromConfig
    }
  }
});

Désormais, comme dans notre usine et notre service, setArtist, getArtist et callItunes seront disponibles dans le contrôleur par lequel nous avons passé myProvider. Voici le contrôleur myProvider (qui est presque identique à notre contrôleur d’usine / service).

app.controller('myProviderCtrl', function($scope, myProvider){
  $scope.data = {};
  $scope.updateArtist = function(){
    myProvider.setArtist($scope.data.artist);
  };

  $scope.submitArtist = function(){
    myProvider.callItunes()
      .then(function(data){
        $scope.data.artistData = data;
      }, function(data){
        alert(data);
      })
  }

  $scope.data.thingFromConfig = myProvider.thingOnConfig;
});

Comme mentionné précédemment, la création d'un service avec Provider permet de modifier certaines variables via la fonction app.config avant que l'objet final ne soit transmis au reste de l'application. Voyons un exemple de cela.

app.config(function(myProviderProvider){
  //Providers are the only service you can pass into app.config
  myProviderProvider.thingFromConfig = 'This sentence was set in app.config. Providers are the only service that can be passed into config. Check out the code to see how it works';
});

Vous pouvez maintenant voir comment 'thingFromConfig' est une chaîne vide dans notre fournisseur, mais lorsque cela apparaît dans le DOM, ce sera 'Cette phrase a été définie…'.


C'est une partie très déroutante pour les débutants et j'ai essayé de le clarifier en termes simples

AngularJS Service: est utilisé pour partager des fonctions utilitaires avec la référence de service dans le contrôleur. Le service est de nature singleton, ainsi, pour un service, une seule instance est créée dans le navigateur et la même référence est utilisée sur toute la page.

Dans le service, nous créons des noms de fonction en tant que propriété avec cet objet.

AngularJS Factory: le but de Factory est également identique à celui de Service, mais dans ce cas, nous créons un nouvel objet et ajoutons des fonctions en tant que propriétés de cet objet.

Fournisseur AngularJS: l’objet de cette opération est à nouveau identique, mais le fournisseur donne le résultat de sa fonction $ get.

La définition et l'utilisation de Service, Factory et Fournisseur sont expliquées à l' http://www.dotnetfunda.com/articles/show/3156/difference-between-angularjs-service-factory-and-provider


Cette réponse aborde le sujet / la question

Comment Factory, Service et Constant - ne constituent-ils que du sucre syntaxique au-dessus d'une recette de fournisseur?

OU

comment l'usine, le service et les fournisseurs sont simailar en interne

essentiellement ce qui se passe est

Lorsque vous faites un factory()it définit que vous avez functionfourni le deuxième argument à provider $getet que vous le retournez ( provider(name, {$get:factoryFn })), tout ce que vous obtenez est, providermais il n'y a pas d'autre propriété / méthode que$get celle-ci provider(cela signifie que vous ne pouvez pas le configurer)

Code source de l'usine

function factory(name, factoryFn, enforce) {
    return provider(name, {
      $get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
    });
};

Lorsque vous faites un service()it, vous fournissez une fabrique () avec un functionqui injecte le constructor(retourne l'instance du constructeur que vous avez fourni dans votre service) et la retourne.

Code source du service

function service(name, constructor) {
    return factory(name, ['$injector', function($injector) {
      return $injector.instantiate(constructor);
    }]);
};

Donc, dans les deux cas, vous obtenez éventuellement un fournisseur $ get configuré pour votre fonction que vous avez fournie, mais vous pouvez donner quelque chose de plus que $ get comme vous pouvez le fournir à l’origine dans provider () pour le bloc de configuration


J'ai remarqué quelque chose d'intéressant en jouant avec les fournisseurs.

La visibilité des produits injectables diffère pour les prestataires de services de celle des services et des usines. Si vous déclarez une constante AngularJS (par exemple, myApp.constant('a', 'Robert');), vous pouvez l'injecter dans des services, des usines et des fournisseurs.

Mais si vous déclarez une "valeur" AngularJS (par exemple., myApp.value('b', {name: 'Jones'});), Vous pouvez l'injecter dans des services et des usines, mais PAS dans la fonction de création de fournisseur. Vous pouvez cependant l'injecter dans la $getfonction que vous définissez pour votre fournisseur. Ceci est mentionné dans la documentation d'AngularJS, mais c'est facile à manquer. Vous pouvez le trouver sur la page% fourniture dans les sections consacrées aux méthodes value et constant.

http://jsfiddle.net/R2Frv/1/

<div ng-app="MyAppName">
    <div ng-controller="MyCtrl">
        <p>from Service: {{servGreet}}</p>
        <p>from Provider: {{provGreet}}</p>
    </div>
</div>
<script>
    var myApp = angular.module('MyAppName', []);

    myApp.constant('a', 'Robert');
    myApp.value('b', {name: 'Jones'});

    myApp.service('greetService', function(a,b) {
        this.greeter = 'Hi there, ' + a + ' ' + b.name;
    });

    myApp.provider('greetProvider', function(a) {
        this.firstName = a;
        this.$get = function(b) {
            this.lastName = b.name;
            this.fullName = this.firstName + ' ' + this.lastName;
            return this;
        };
    });

    function MyCtrl($scope, greetService, greetProvider) {
        $scope.servGreet = greetService.greeter;
        $scope.provGreet = greetProvider.fullName;
    }
</script>

Juste pour clarifier les choses, depuis la source AngularJS, vous pouvez voir qu'un service appelle simplement la fonction usine qui à son tour appelle la fonction fournisseur:

function factory(name, factoryFn) { 
    return provider(name, { $get: factoryFn }); 
}

function service(name, constructor) {
    return factory(name, ['$injector', function($injector) {
      return $injector.instantiate(constructor);
    }]);
}

Ma compréhension est très simple ci-dessous.

Usine: vous créez simplement un objet à l'intérieur de l'usine et vous le retournez.

Un service:

Vous avez juste une fonction standard qui utilise ce mot clé pour définir une fonction.

Fournisseur:

$getVous définissez un objet que vous pouvez utiliser pour obtenir l’objet qui renvoie les données.


Pour moi, le meilleur moyen de comprendre la différence est:

var service, factory;
service = factory = function(injection) {}

Comment AngularJS instancie des composants particuliers (simplifié):

// service
var angularService = new service(injection);

// factory
var angularFactory = factory(injection);

Ainsi, pour le service, le composant AngularJS devient l'instance d'objet de la classe représentée par la fonction de déclaration de service. Pour l'usine, il s'agit du résultat renvoyé par la fonction de déclaration d'usine. L’usine peut se comporter comme le service:

var factoryAsService = function(injection) {
  return new function(injection) {
    // Service content
  }
}

La façon la plus simple de penser est la suivante:

  • Le service est une instance d'objet singleton. Utilisez les services si vous souhaitez fournir un objet singleton pour votre code.
  • L'usine est une classe. Utilisez des fabriques si vous souhaitez fournir des classes personnalisées pour votre code (impossible avec des services car elles sont déjà instanciées).

L'exemple de «classe» d'usine est fourni dans les commentaires, ainsi que la différence de fournisseur.


Comme l'ont souligné à juste titre plusieurs personnes, une usine, un fournisseur, un service et même une valeur et une constante sont des versions identiques. Vous pouvez disséquer le plus général providerdans chacun d'eux. Ainsi:

Voici l'article de cette image:


Discutons les trois manières de gérer la logique métier dans AngularJS de manière simple: ( Inspiré du cours Coursera AngularJS de Yaakov )

SERVICE :

Syntaxe:

app.js

 var app = angular.module('ServiceExample',[]);
 var serviceExampleController =
              app.controller('ServiceExampleController', ServiceExampleController);
 var serviceExample = app.service('NameOfTheService', NameOfTheService);

 ServiceExampleController.$inject = ['NameOfTheService'] //protects from minification of js files

function ServiceExampleController(NameOfTheService){
     serviceExampleController = this;
     serviceExampleController.data = NameOfTheService.getSomeData();
 }

function NameOfTheService(){
     nameOfTheService = this;
     nameOfTheService.data = "Some Data";
     nameOfTheService.getSomeData = function(){
           return nameOfTheService.data;
     }     
}

index.html

<div ng-controller = "ServiceExampleController as serviceExample">
   {{serviceExample.data}}
</div>

Caractéristiques du service:

  1. Lazily Instancié : S'il n'est pas injecté, il ne sera jamais instancié. Donc, pour l'utiliser, il faudra l'injecter dans un module.
  2. Singleton : si injecté à plusieurs modules, tous n’auront accès qu’à une seule instance. C'est pourquoi il est très pratique de partager des données entre différents contrôleurs.

USINE

Voyons d'abord la syntaxe:

app.js :

var app = angular.module('FactoryExample',[]);
var factoryController = app.controller('FactoryController', FactoryController);
var factoryExampleOne = app.factory('NameOfTheFactoryOne', NameOfTheFactoryOne);
var factoryExampleTwo = app.factory('NameOfTheFactoryTwo', NameOfTheFactoryTwo);

//first implementation where it returns a function
function NameOfTheFactoryOne(){
   var factory = function(){
      return new SomeService();
    }
   return factory;
}

//second implementation where an object literal would be returned
function NameOfTheFactoryTwo(){
   var factory = {
      getSomeService : function(){
          return new SomeService();
       }
    };
   return factory;
}

Maintenant, en utilisant les deux ci-dessus dans le contrôleur:

 var factoryOne = NameOfTheFactoryOne() //since it returns a function
 factoryOne.someMethod();

 var factoryTwo = NameOfTheFactoryTwo.getSomeService(); //accessing the object
 factoryTwo.someMethod();

Caractéristiques de l'usine:

  1. Suit le modèle de conception d'usine. L'usine est un lieu central qui produit de nouveaux objets ou fonctions.
  2. Non seulement produit singleton, mais des services personnalisables.
  3. La .service()méthode est une fabrique qui produit toujours le même type de service, un singleton, sans aucun moyen facile de configurer son comportement. Cette .service()méthode est généralement utilisée comme raccourci pour quelque chose qui ne nécessite aucune configuration.

FOURNISSEUR

Regardons d'abord la syntaxe:

angular.module('ProviderModule', [])
.controller('ProviderModuleController', ProviderModuleController)
.provider('ServiceProvider', ServiceProvider)
.config(Config); //optional

Config.$inject = ['ServiceProvider'];
function Config(ServiceProvider) {
  ServiceProvider.defaults.maxItems = 10; //some default value
}


ProviderModuleController.$inject = ['ServiceProvider'];
function ProviderModuleController(ServiceProvider) {
  //some methods
}

function ServiceProvider() {
  var provider = this;

  provider.defaults = {
    maxItems: 10
  };

  provider.$get = function () {
    var someList = new someListService(provider.defaults.maxItems);

    return someList;
  };
}

}

Caractéristiques du fournisseur:

  1. Fournisseur est la méthode la plus souple de création de services dans Angular.
  2. Non seulement nous pouvons créer une fabrique configurable de manière dynamique, mais au moment de l’utiliser, avec la méthode du fournisseur, nous pouvions personnaliser la fabrique une seule fois lors du démarrage de l’application entière.
  3. La fabrique peut ensuite être utilisée dans toute l'application avec des paramètres personnalisés. En d'autres termes, nous pouvons configurer cette usine avant le démarrage de l'application. En fait, dans la documentation angulaire, il est mentionné que la méthode du fournisseur est ce qui est réellement exécuté en arrière-plan lorsque nous configurons nos services avec l'une .serviceou l' autre des .factoryméthodes.
  4. Le $getest une fonction directement attachée à l'instance du fournisseur. Cette fonction est une fonction d' usine . En d'autres termes, c'est comme celui que nous utilisons pour fournir à la .factoryméthode. Dans cette fonction, nous créons notre propre service. Cette $getpropriété, c'est une fonction, est ce qui fait du fournisseur un fournisseur . AngularJS s'attend à ce que le fournisseur ait une propriété $ get dont la valeur est une fonction qu'Angular traitera comme une fonction d'usine. Mais ce qui rend toute l’installation de ce fournisseur très spéciale, c’est le fait que nous pouvons fournir un configobjet à l’intérieur du fournisseur de service, ce qui vient généralement avec des valeurs par défaut que nous pouvons écraser ultérieurement dans l’étape, où nous pouvons configurer toute l’application.

En utilisant comme référence cette page et la docs.angularjs.org/guide/providers (qui semble s’être grandement améliorée depuis la dernière fois que j’ai regardé), j’ai monté la démo du monde réel (-ish) suivante qui utilise 4 des 5 saveurs de fournisseur; Valeur, constante, usine et fournisseur complet.

HTML:

<div ng-controller="mainCtrl as main">
    <h1>{{main.title}}*</h1>
    <h2>{{main.strapline}}</h2>
    <p>Earn {{main.earn}} per click</p>
    <p>You've earned {{main.earned}} by clicking!</p>
    <button ng-click="main.handleClick()">Click me to earn</button>
    <small>* Not actual money</small>
</div>

app

var app = angular.module('angularProviders', []);

// A CONSTANT is not going to change
app.constant('range', 100);

// A VALUE could change, but probably / typically doesn't
app.value('title', 'Earn money by clicking');
app.value('strapline', 'Adventures in ng Providers');

// A simple FACTORY allows us to compute a value @ runtime.
// Furthermore, it can have other dependencies injected into it such
// as our range constant.
app.factory('random', function randomFactory(range) {
    // Get a random number within the range defined in our CONSTANT
    return Math.random() * range;
});

// A PROVIDER, must return a custom type which implements the functionality 
// provided by our service (see what I did there?).
// Here we define the constructor for the custom type the PROVIDER below will 
// instantiate and return.
var Money = function(locale) {

    // Depending on locale string set during config phase, we'll
    // use different symbols and positioning for any values we 
    // need to display as currency
    this.settings = {
        uk: {
            front: true,
            currency: '£',
            thousand: ',',
            decimal: '.'
        },
        eu: {
            front: false,
            currency: '€',
            thousand: '.',
            decimal: ','
        }
    };

    this.locale = locale;
};

// Return a monetary value with currency symbol and placement, and decimal 
// and thousand delimiters according to the locale set in the config phase.
Money.prototype.convertValue = function(value) {

    var settings = this.settings[this.locale],
        decimalIndex, converted;

    converted = this.addThousandSeparator(value.toFixed(2), settings.thousand);

    decimalIndex = converted.length - 3;

    converted = converted.substr(0, decimalIndex) +
        settings.decimal +
        converted.substr(decimalIndex + 1);    

    converted = settings.front ?
            settings.currency + converted : 
            converted + settings.currency; 

    return converted;   
};

// Add supplied thousand separator to supplied value
Money.prototype.addThousandSeparator = function(value, symbol) {
   return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, symbol);
};

// PROVIDER is the core recipe type - VALUE, CONSTANT, SERVICE & FACTORY
// are all effectively syntactic sugar built on top of the PROVIDER construct
// One of the advantages of the PROVIDER is that we can configure it before the
// application starts (see config below).
app.provider('money', function MoneyProvider() {

    var locale;

    // Function called by the config to set up the provider
    this.setLocale = function(value) {
        locale = value;   
    };

    // All providers need to implement a $get method which returns
    // an instance of the custom class which constitutes the service
    this.$get = function moneyFactory() {
        return new Money(locale);
    };
});

// We can configure a PROVIDER on application initialisation.
app.config(['moneyProvider', function(moneyProvider) {
    moneyProvider.setLocale('uk');
    //moneyProvider.setLocale('eu'); 
}]);

// The ubiquitous controller
app.controller('mainCtrl', function($scope, title, strapline, random, money) {

    // Plain old VALUE(s)
    this.title = title;
    this.strapline = strapline;

    this.count = 0;

    // Compute values using our money provider    
    this.earn = money.convertValue(random); // random is computed @ runtime
    this.earned = money.convertValue(0);

    this.handleClick = function() { 
        this.count ++;
        this.earned = money.convertValue(random * this.count);
    };
});

demo travail .


Essentiellement, fournisseur, usine et service sont tous des services. Une Factory est un cas particulier de Service où tout ce dont vous avez besoin est une fonction $ get (), vous permettant de l'écrire avec moins de code.

Les principales différences entre les services, les usines et les fournisseurs sont leur complexité. Les services sont la forme la plus simple, les usines sont un peu plus robustes et les fournisseurs sont configurables au moment de l'exécution.

Voici un résumé de quand utiliser chacun:

Usine : La valeur que vous fournissez doit être calculée en fonction d'autres données.

Service : Vous retournez un objet avec des méthodes.

Fournisseur : vous voulez pouvoir configurer, pendant la phase de configuration, l'objet qui va être créé avant sa création. Utilisez le fournisseur principalement dans la configuration de l'application, avant que l'application ne soit complètement initialisée.


Pour moi, la révélation est venue quand j'ai réalisé qu'ils fonctionnaient tous de la même manière: en exécutant quelque chose une fois , en stockant la valeur qu'ils obtenaient, puis en augmentant la même valeur stockée lorsqu'elle était référencée par injection de dépendance .

Disons que nous avons:

app.factory('a', fn);
app.service('b', fn);
app.provider('c', fn);

La différence entre les trois est que:

  1. aLa valeur stockée de vient de courir fn.
  2. bLa valeur stockée vient de newing fn.
  3. cLa valeur stockée de vient tout d'abord d'obtenir une instance en newing fn, puis en exécutant une $getméthode de l'instance.

Cela signifie qu’il y a quelque chose comme un objet cache dans AngularJS, dont la valeur de chaque injection n’est attribuée qu’une fois, lorsqu’ils ont été injectés pour la première fois et où:

cache.a = fn()
cache.b = new fn()
cache.c = (new fn()).$get()

C'est pourquoi nous utilisons des thisservices et définissons un this.$getfournisseur.


Résumé de la docs.angularjs.org/guide/providers :

  • Il existe cinq types de recettes qui définissent comment créer des objets: Value , Factory , Service , Provider et Constant .
  • Factory et Service sont les recettes les plus couramment utilisées. La seule différence entre eux est que la recette de service fonctionne mieux pour les objets d'un type personnalisé, tandis que la fabrique peut produire des primitives et des fonctions JavaScript.
  • La recette du fournisseur est le type de recette principale et toutes les autres ne sont que du sucre syntaxique.
  • Le fournisseur est le type de recette le plus complexe. Vous n'en avez pas besoin, sauf si vous créez un élément de code réutilisable nécessitant une configuration globale.

Meilleures réponses de SO:

https://.com/a/26924234/165673 (<- GOOD) https://.com/a/27263882/165673
https://.com/a/16566144/165673


Un peu tard pour la fête. Mais j’ai pensé que c’était plus utile pour ceux qui voudraient apprendre (ou avoir une clarté) sur le développement de services personnalisés JS angulaires à l’aide de méthodologies d’usine, de service et de fournisseur.

Je suis tombé sur cette vidéo qui explique clairement les méthodologies d'usine, de service et de fournisseur pour développer des services personnalisés AngularJS:

https://www.youtube.com/watch?v=oUXku28ex-M

Code source: http://www.techcbt.com/Post/353/Angular-JS-basics/how-to-develop-angularjs-custom-service

Le code affiché ici est directement copié de la source ci-dessus, pour le plus grand bénéfice des lecteurs.

Le code du service personnalisé basé sur "usine" est le suivant (qui accompagne les versions sync et async avec l'appel du service http):

var app = angular.module("app", []);
app.controller('emp', ['$scope', 'calcFactory',
  function($scope, calcFactory) {
    $scope.a = 10;
    $scope.b = 20;

    $scope.doSum = function() {
      //$scope.sum = calcFactory.getSum($scope.a, $scope.b); //synchronous
      calcFactory.getSum($scope.a, $scope.b, function(r) { //aynchronous
        $scope.sum = r;
      });
    };

  }
]);

app.factory('calcFactory', ['$http', '$log',
  function($http, $log) {
    $log.log("instantiating calcFactory..");
    var oCalcService = {};

    //oCalcService.getSum = function(a,b){
    //	return parseInt(a) + parseInt(b);
    //};

    //oCalcService.getSum = function(a, b, cb){
    //	var s = parseInt(a) + parseInt(b);
    //	cb(s);
    //};

    oCalcService.getSum = function(a, b, cb) { //using http service

      $http({
        url: 'http://localhost:4467/Sum?a=' + a + '&b=' + b,
        method: 'GET'
      }).then(function(resp) {
        $log.log(resp.data);
        cb(resp.data);
      }, function(resp) {
        $log.error("ERROR occurred");
      });
    };

    return oCalcService;
  }
]);

Le code de la méthodologie "service" pour les services personnalisés (ceci est assez similaire à "factory", mais différent du point de vue de la syntaxe):

var app = angular.module("app", []);
app.controller('emp', ['$scope', 'calcService', function($scope, calcService){
	$scope.a = 10;
	$scope.b = 20;

	$scope.doSum = function(){
		//$scope.sum = calcService.getSum($scope.a, $scope.b);
		
		calcService.getSum($scope.a, $scope.b, function(r){
			$scope.sum = r;
		});		
	};

}]);

app.service('calcService', ['$http', '$log', function($http, $log){
	$log.log("instantiating calcService..");
	
	//this.getSum = function(a,b){
	//	return parseInt(a) + parseInt(b);
	//};

	//this.getSum = function(a, b, cb){
	//	var s = parseInt(a) + parseInt(b);
	//	cb(s);
	//};

	this.getSum = function(a, b, cb){
		$http({
			url: 'http://localhost:4467/Sum?a=' + a + '&b=' + b,
			method: 'GET'
		}).then(function(resp){
			$log.log(resp.data);
			cb(resp.data);
		},function(resp){
			$log.error("ERROR occurred");
		});
	};

}]);

Le code de la méthodologie "fournisseur" pour les services personnalisés (nécessaire si vous souhaitez développer un service pouvant être configuré):

var app = angular.module("app", []);
app.controller('emp', ['$scope', 'calcService', function($scope, calcService){
	$scope.a = 10;
	$scope.b = 20;

	$scope.doSum = function(){
		//$scope.sum = calcService.getSum($scope.a, $scope.b);
		
		calcService.getSum($scope.a, $scope.b, function(r){
			$scope.sum = r;
		});		
	};

}]);

app.provider('calcService', function(){

	var baseUrl = '';

	this.config = function(url){
		baseUrl = url;
	};

	this.$get = ['$log', '$http', function($log, $http){
		$log.log("instantiating calcService...")
		var oCalcService = {};

		//oCalcService.getSum = function(a,b){
		//	return parseInt(a) + parseInt(b);
		//};

		//oCalcService.getSum = function(a, b, cb){
		//	var s = parseInt(a) + parseInt(b);
		//	cb(s);	
		//};

		oCalcService.getSum = function(a, b, cb){

			$http({
				url: baseUrl + '/Sum?a=' + a + '&b=' + b,
				method: 'GET'
			}).then(function(resp){
				$log.log(resp.data);
				cb(resp.data);
			},function(resp){
				$log.error("ERROR occurred");
			});
		};		

		return oCalcService;
	}];

});

app.config(['calcServiceProvider', function(calcServiceProvider){
	calcServiceProvider.config("http://localhost:4467");
}]);

Enfin, l'interface utilisateur qui fonctionne avec l'un des services ci-dessus:

<html>
<head>
	<title></title>
	<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js" ></script>
	<script type="text/javascript" src="t03.js"></script>
</head>
<body ng-app="app">
	<div ng-controller="emp">
		<div>
			Value of a is {{a}},
			but you can change
			<input type=text ng-model="a" /> <br>

			Value of b is {{b}},
			but you can change
			<input type=text ng-model="b" /> <br>

		</div>
		Sum = {{sum}}<br>
		<button ng-click="doSum()">Calculate</button>
	</div>
</body>
</html>


Une clarification supplémentaire est que les usines peuvent créer des fonctions / primitives alors que les services ne le peuvent pas. Découvrez ce jsFiddle basé sur Epokk: http://jsfiddle.net/skeller88/PxdSP/1351/ .

La fabrique retourne une fonction qui peut être appelée:

myApp.factory('helloWorldFromFactory', function() {
  return function() {
    return "Hello, World!";
  };
});

La fabrique peut également renvoyer un objet avec une méthode pouvant être appelée:

myApp.factory('helloWorldFromFactory', function() {
  return {
    sayHello: function() {
      return "Hello, World!";
    }
  };
});

Le service renvoie un objet avec une méthode pouvant être appelée:

myApp.service('helloWorldFromService', function() {
  this.sayHello = function() {
     return "Hello, World!";
  };
});

Pour plus de détails, voir un article que j'ai écrit sur la différence: http://www.shanemkeller.com/tldr-services-vs-factories-in-angular/





angularjs-provider