Pour les débutants, quelqu'un peut-il expliquer clairement la différence entre Service, Factory et Provider dans AngularJS?


Réponse 1:

AngularJS: Différence entre service vs fournisseur vs usine

Si vous recherchez cela, c'est probablement parce que vous essayez de déterminer lequel vous convient le mieux. Ou parce que vous les avez rencontrés et que vous essayez de déterminer la différence parce qu'ils semblent similaires.

Si vous pensez qu'ils sont similaires, vous avez raison. Ils sont très similaires. En fait, c'est la même chose.

Ce sont tous des fournisseurs. L'usine et le service ne sont que des cas particuliers du fournisseur, mais vous pouvez accomplir tout ce que vous voulez en utilisant simplement le fournisseur. Je vais te montrer.

Le fournisseur

Nous allons créer un fournisseur qui renvoie une valeur et afficher simplement cette valeur, vous feriez ceci:

var mod = angular.module ("MonModule", []); mod.provider ("myProvider", function () {this. $ get = function () {return "My Value";};}); mod.controller ("MyController", fonction (myProvider) {console.log ("MyController - myProvider:" + myProvider);}); CONSOLE OUTPUT MyController - myProvider: Ma valeur

Un exemple interactif de travail peut être trouvé à: JS Fiddle.

Là, donc un «fournisseur» au cœur vous permet de «fournir» une valeur. Cette valeur pourrait être n'importe quoi. Dans ce cas, c'est une chaîne dont la valeur est «Ma valeur», mais il aurait pu facilement s'agir d'une fonction ou d'un objet.

Remarque dans d'autres exemples de code, je vais exclure le tag et la définition du mod dans le but de garder les extraits de code courts et précis.

Angular n'obtient la valeur qu'une seule fois - jamais

Notez que l'angulaire n'obtient la valeur qu'une seule fois, quel que soit le nombre de fois où le fournisseur est injecté. Cela signifie qu'il n'appelle $ get () qu'une seule fois, stocke la valeur fournie par $ get () et vous donne à chaque fois la même valeur stockée.

Pour vous montrer ce que je veux dire, je vais créer un autre contrôleur et injecter à nouveau le fournisseur avec une déclaration de console afin que vous puissiez voir ce qui se passe.

mod.provider ("myProvider", function () {this. $ get = function () {console.log ("MyProviderFunction. $ get () appelé."); // ADDED cette ligne retourne "My Value";}; }); mod.controller ("MyController", fonction (myProvider) {console.log ("MyController - myProvider:" + myProvider);}); mod.controller ("MyController2", fonction (myProvider) {// ADDED this controller console.log ("MyController2 - myProvider:" + myProvider);}); SORTIE CONSOLE MyProviderFunction. $ Get () appelé. MyController - myProvider: Ma valeur MyController2 - myProvider: Ma valeur

Ouvrir dans JS Fiddle

Comme vous pouvez le voir, la fonction $ get () n'a été appelée qu'une seule fois.

Notez que nous avons écrit un tas de code pour le fournisseur uniquement dans le but de créer une méthode appelée $ get (). Pourquoi pas au lieu de donner à angular une fonction qui définit une autre fonction, pourquoi ne pas simplement lui donner la fonction que nous voulons exécuter directement à la place? Eh bien, c'est ce que Angular appelle une usine.

Une usine

Avec une usine, vous fournissez simplement le corps de la fonction pour la méthode $ get et Angular fait le reste. Voici à quoi ressemble le nouveau code, comme vous le verrez, il se comporte exactement de la même manière.

mod.factory ("myProvider", function () {// CHANGED "provider" en "factory" console.log ("Factory function called."); return "My Value";}); mod.controller ("MyController", fonction (myProvider) {console.log ("MyController - myProvider:" + myProvider);}); mod.controller ("MyController2", fonction (myProvider) {console.log ("MyController2 - myProvider:" + myProvider);}); SORTIE CONSOLE Fonction d'usine appelée. MyController - myProvider: Ma valeur MyController2 - myProvider: Ma valeur

Ouvrir dans JS Fiddle

Maintenant, vous vous demandez peut-être pourquoi utiliseriez-vous un fournisseur si vous pouvez accomplir la même chose avec une usine avec moins de code. Il y a quelques raisons et j'y reviendrai plus tard, en ce moment je veux rester fidèle au titre de cet article et aborder la différence entre ces deux (fournisseur et usine) et un service.

Jusqu'à présent, nous avons renvoyé une simple valeur de chaîne, mais dans la pratique, ce que nous voulons probablement retourner la plupart du temps est un objet. Eh bien, cela ne changerait pas beaucoup notre exemple, nous pouvons très facilement échanger la chaîne que nous renvoyons avec un objet à la place.

Par exemple, faisons cela en renvoyant un objet qui contient une fonction appelée getValue (). Maintenant, il existe plusieurs façons de créer un objet en JavaScript, nous allons utiliser l'approche «Object Constructor» où nous créons une fonction qui remplit un objet avec des propriétés et des fonctions et utilise le nouveau mot-clé pour l'instancier.

function MyObject () {// ADDED notre constructeur d'objet this.getValue = function () {return "My Value"; }; } mod.factory ("myProvider", function () {console.log ("Factory function called."); return new MyObject (); // CREATE une instance de notre objet}); mod.controller ("MyController", function (myProvider) {console.log ("MyController - myProvider:" + myProvider.getValue ()); // MODIFIÉ pour appeler getValue ()}); mod.controller ("MyController2", function (myProvider) {console.log ("MyController2 - myProvider:" + myProvider.getValue ()); // CHANGED pour appeler getValue ()}); SORTIE CONSOLE Fonction d'usine appelée. MyController - myProvider: Ma valeur MyController2 - myProvider: Ma valeur

Ouvrir dans JS Fiddle

Maintenant, je veux apporter une petite modification à cela, car cela conduira bien au concept suivant. Dans notre exemple, nous créons la fonction «Object Constructor» MyObject (), mais comme nous ne l'instancions qu'au même endroit, nous pouvons utiliser une fonction anonyme à la place.

Il s'agit d'un tout petit ajustement. Au lieu de cela:

function MyObject () {this.getValue = function () {return "My Value"; }; } mod.factory ("myProvider", function () {console.log ("Factory function called."); return new MyObject ();});

Nous faisons ceci:

mod.factory ("myProvider", function () {console.log ("Factory function called."); return new function () {// INLINED notre constructeur d'objet this.getValue = function () {return "My Value"; };};});

Donc, le tout ressemble maintenant à ceci:

mod.factory ("myProvider", function () {console.log ("Factory function called."); return new function () {// INLINED notre constructeur d'objet this.getValue = function () {return "My Value"; };};}); mod.controller ("MyController", fonction (myProvider) {console.log ("MyController - myProvider:" + myProvider.getValue ());}); mod.controller ("MyController2", fonction (myProvider) {console.log ("MyController2 - myProvider:" + myProvider.getValue ());});

Ouvrir dans JS Fiddle

Maintenant que toute notre usine est composée d'un seul objet, ce ne serait pas bien si nous pouvions simplement donner à Angular la fonction de constructeur d'objet au lieu d'avoir à écrire cette usine au look funky. Eh bien, vous avez de la chance, c'est exactement ce qu'est un service.

À votre service

Voici ce même code, sauf en utilisant un service au lieu d'une usine.

mod.service ("myProvider", function () {// CHANGED "factory" to "service" // NOTE que la seule fonction transmise est le constructeur d'objet avant this.getValue = function () {return "My Value" ;};}); mod.controller ("MyController", fonction (myProvider) {console.log ("MyController - myProvider:" + myProvider.getValue ());}); mod.controller ("MyController2", fonction (myProvider) {console.log ("MyController2 - myProvider:" + myProvider.getValue ());}); SORTIE CONSOLE MyController - myProvider: My Value MyController2 - myProvider: My Value

Ouvrir dans JS Fiddle

Fournisseur vs usine vs service

Donc, en résumé, le fournisseur, l'usine et le service sont tous des fournisseurs. Une usine est un cas particulier de fournisseur lorsque tout ce dont vous avez besoin est une fonction $ get (). Il vous permet de l'écrire avec moins de code. Un service est un cas particulier de fabrique lorsque vous souhaitez renvoyer une instance d'un nouvel objet, avec le même avantage d'écrire moins de code.

Quand utiliser l'un par rapport à l'autre?

La réponse est que vous utilisez la version la plus spécialisée qui atteint votre objectif. Supposons par exemple que vous renvoyez un objet existant défini ailleurs qui prend des arguments de constructeur. Vous ne pouvez pas passer d'arguments au service, vous devriez donc passer l'appel avec une fabrique à la place.

mod.factory ("myProvider", function () {console.log ("Factory function called."); return new SomeMessageBoxClass ("custom argument");});

L'un des principaux facteurs de décision entre un fournisseur et une fabrique est de savoir si vous souhaitez pouvoir configurer l'objet qui est généré avant qu'il ne soit généré. Pour ce faire, appelez module.config () et obtenez une instance du fournisseur lui-même (au lieu de l'objet renvoyé par le fournisseur). Pour ce faire, ajoutez «Fournisseur» à la fin du nom de votre fournisseur lorsque vous l'injectez.

Voici un exemple de la façon dont vous le feriez:

mod.provider ("myProvider", function () {this.value = "My Value"; this.setValue = function (newValue) {this.value = newValue;}; this. $ get = function () {return this. valeur; }; }); mod.controller ("MyController", fonction (myProvider) {console.log ("MyController - myProvider:" + myProvider);}); mod.config (function (myProviderProvider) {// Section de configuration ADDED // Notez le suffixe "Provider" supplémentaire myProviderProvider.setValue ("New Value");});

Cela couvre quand utiliser les trois fournisseurs: fournisseur, usine et service. Il y a un fournisseur supplémentaire qui n'a pas été mentionné ici qui est encore un autre cas spécial et c'est le fournisseur de valeur.

Si vous vous souvenez de la première fois que nous avons introduit le fournisseur d'usine ci-dessus, nous avons donné l'exemple simple de retour d'une valeur de chaîne. Cela ressemblait à ceci:

mod.factory ("myProvider", function () {return "My Value";});

Eh bien, nous aurions pu le faire en utilisant le fournisseur de valeur à la place, encore une fois l'avantage étant que vous pouvez le faire avec moins de code. Le code ci-dessous fait la même chose que le code ci-dessus:

mod.value ("myProvider", "My Value");

Alors, quand utiliseriez-vous l'un contre l'autre? Vraisemblablement, vous utiliseriez le fournisseur d'usine lorsque vous souhaitez calculer la valeur en fonction d'autres données, par exemple des données d'un autre fournisseur de valeur ou d'une source externe. Et / ou lorsque vous souhaitez calculer la valeur si et seulement lors de sa première demande. Voici quelques exemples:

// Exemple où l'usine dépend d'un fournisseur "value" mod.value ("multiple", 3); mod.factory ("valeur", fonction (multiple) {return 10 * multiple;}); // Exemple où l'usine dépend des données externes mod.factory ("valeur", fonction (multiple) {var multiple = getDateFromExternalPage (); return 10 * multiple;});

Ai-je laissé entendre que la valeur était le seul autre fournisseur? Eh bien j'ai menti, il y en a un autre qui est très similaire à la valeur avec deux différences mineures. Ce fournisseur est appelé constant.

La différence entre valeur et constante est qu'une valeur spécifiée à l'aide de constante est disponible pendant la phase de configuration. Vous vous souvenez peut-être plus tôt que j'ai mentionné que le fournisseur était accessible depuis la phase de configuration, mais le service et l'usine ne l'étaient pas.

Eh bien, c'est la même chose pour la valeur et la constante. constante est disponible à partir de la phase de configuration et la valeur ne l'est pas. L'autre différence est que le nom implique que vous ne pouvez pas modifier la valeur d'une constante. La première valeur que vous lui attribuez est la valeur qu'elle conserve, si vous essayez de lui attribuer une valeur différente plus tard, elle sera ignorée.

Voici un exemple:

mod.value ("myValue", "First Assignment"); mod.value ("myValue", "Second Assignment"); mod.constant ("myConstant", "First Assignment"); mod.constant ("myConstant", "Second Assignment"); mod.controller ("MyController", fonction (myValue, myConstant) {console.log ("myValue:" + myValue); console.log ("myConstant:" + myConstant);}); SORTIE CONSOLE myValue: Deuxième affectation myConstant: Première affectation

Voici un résumé de l'utilisation de chacun:

valeur

Vous fournissez une valeur littérale simple.

mod.value ("myValue", 10);
    

constant

Vous devez pouvoir accéder à cette valeur pendant la phase de configuration. (en utilisant .config ())

mod.constant ("maValeur", 10); mod.config (function (myValue) {console.log (myValue);});

usine

La valeur que vous fournissez doit être calculée sur la base d'autres données.

mod.factory ("myFactory", function () {return 10;});
        

un service

Vous retournez un objet avec des méthodes.

mod.service ("myService", function () {var name = "Bob"; this.setName = function (newName) {this.name = newName;}; this.getName = function () {return this.name;} });
        

fournisseur

Vous voulez pouvoir configurer, pendant la phase de configuration, l'objet qui va être créé avant sa création.

mod.provider ("greeter", function () {var name; this.setName = function (newName) {name = newName;}; this. $ get = function () {return new function () {this.sayHi = function () {console.log ("Hi" + nom;};};};}); mod.config (fonction (greeterProvider) {greeterProvider.setName ("John");});
        

Pour ramener le point à la maison une dernière fois, voici une image d'un fournisseur avec les parties usine, valeur et service mises en évidence:


Réponse 2:

En interne, AngularJS utilise Factory pour créer un objet de service et utilise Provider pour créer un objet Factory.

Une usine fait,

  1. Créer un objet / une instance Construire / initialiser l'objet / l'instanceur créé retourner l'objet / l'instance créé

Pour définir le contexte, considérez Angular Factory comme modèle de conception Abstract Factory. AngularJS vous donne la possibilité de créer l'objet de votre choix en utilisant votre méthode d'usine, vous retournez l'objet créé pour que votre application l'utilise comme service.

Exemple ci-dessous, vous avez le choix entre deux passerelles de paiement, quelqu'un utilisant votre code / bibliothèque, votre méthode d'usine peut faire le choix de créer un objet Paypal ou Stripe. Ceci est très similaire à Abstract Factory, les utilisateurs de paymentService ne savent pas quel service a été utilisé pour la passerelle de paiement.

var myModule = angular.module ('monModule', []); myModule.constant ("PaymentGatewayName", "Stripe"); // ou "Paypal" myModule.factory ('paymentService', fonction (PaymentGatewayName) {var paymentService; // vous décidez quel objet créer en fonction des besoins de l'entreprise // StripeGateway et PaypalGateway sont des classes JavaScript // contient une implémentation spécifique à la passerelle si ( PaymentGatewayName == "Stripe") {paymentService = new StripeGateway (); // code personnalisé pour initialiser la passerelle stripe} else (PaymentGatewayName == "Paypal") {paymentService = new PaypalGateway (); // code personnalisé pour initialiser paypal} / / code personnalisé pour initialiser paymentService return paymentService;});

Un code de service ressemble à ceci, vous remarquez «ce» mot-clé, cela signifie que l'objet est déjà créé pour vous par Angular Core, vous ne contrôlez plus la création d'objet.

var myModule = angular.module ('monModule', []); myModule.service ('Cache', function () {var localVariable = ""; // n'est pas accessible en dehors de this.cacheSize = 5; // 5 Mo this.objectsSize = 1000; // max 1000 objets this.put = function (clé, valeur) {...} this.get = function (get) {return ...}});

Réponse 3:

La grande question dans AngularJS: Service vs Factory v / s Provider. Que dois-je utiliser?

Il existe des tonnes de ressources sur Internet qui traitent du sujet. Il s'avère que cette question apparaît toujours chaque semaine sur des canaux différents, et même après avoir lu les dix meilleures réponses sur StackOverflow, ce n'est toujours pas très clair.

Si vous pensez qu'ils sont similaires, vous avez raison. Ils sont très similaires. En fait, c'est la même chose, ce sont tous des fournisseurs.

Lire l'article complet -> AngularJS: Service v / s Factory v / s Provider - Get Interview Ready in 15 Minutes