Je suis sûr que cela a pris la peine de vous - il m'a gêné pendant un certain temps maintenant. Quelles sont les différences entre AngularJS du module Service
, Provider
et Factory
?
Réponses
Trop de publicités?À partir de l'angle de la liste de diffusion, j'ai eu une incroyable thread qui explique le service vs usine vs fournisseur et leur injection d'utilisation. Compiler les réponses:
Services
Syntaxe: module.service( 'serviceName', function );
Résultat: Lors de la déclaration de serviceName comme un produit injectable argument , vous sera fourni avec une instance de la fonction. En d'autres mots, new FunctionYouPassedToService()
.
Les usines
Syntaxe: module.factory( 'factoryName', function );
Résultat: Lors de la déclaration de factoryName comme un produit injectable argument, vous sera fourni avec la valeur qui est retournée par l'invocation de la fonction de référence transmise au module.usine.
Les fournisseurs de
Syntaxe: module.provider( 'providerName', function );
Résultat: Lors de la déclaration de providerName comme un produit injectable argument , vous sera fourni avec ProviderFunction().$get()
. La fonction constructeur est instancié avant l' $méthode get est appelé - ProviderFunction est la fonction de référence transmise au module.fournisseur de.
Les fournisseurs ont l'avantage qu'ils peuvent être configurés lors de la configuration du module de phase.
Voir ici pour le code fourni: http://jsbin.com/ohamub/1/edit
Voici une autre explication par Misko:
provide.value('a', 123);
function Controller(a) {
expect(a).toEqual(123);
}
Dans ce cas, l'injecteur renvoie simplement la valeur est. Mais que faire si vous voulez calculer la valeur? Ensuite, utilisez une usine
provide.factory('b', function(a) {
return a*2;
});
function Controller(b) {
expect(b).toEqual(246);
}
Si l'usine est une fonction qui est responsable de la création de la valeur. Notez que la fonction de fabrication de pouvez demander d'autres dépendances.
Mais que faire si vous voulez être plus OO et ont une classe appelée Greeter?
function Greeter(a) {
this.greet = function() {
return 'Hello ' + a;
}
}
Ensuite instancier vous devez écrire
provide.factory('greeter', function(a) {
return new Greeter(a);
});
Ensuite, nous pourrions demander le "greeter" dans le contrôleur comme ceci
function Controller(greeter) {
expect(greeter instanceof Greeter).toBe(true);
expect(greeter.greet()).toEqual('Hello 123');
}
Mais c'est trop verbeux. Une façon plus simple d'écrire ce serait provider.service('greeter', Greeter);
Mais que faire si nous voulions pour configurer l' Greeter
de la classe avant l'injection? Ensuite, nous pourrions écrire
provide.provider('greeter2', function() {
var salutation = 'Hello';
this.setSalutation = function(s) {
salutation = s;
}
function Greeter(a) {
this.greet = function() {
return salutation + ' ' + a;
}
}
this.$get = function(a) {
return new Greeter(a);
};
});
Nous pouvons alors faire ceci:
angular.module('abc', []).config(function(greeter2Provider) {
greeter2Provider.setSalutation('Halo');
});
function Controller(greeter2) {
expect(greeter2.greet()).toEqual('Halo 123');
}
Comme une note de côté, service
, factory
, et value
sont toutes dérivées du fournisseur.
provider.service = function(name, Class) {
provider.provide(name, function() {
this.$get = function($injector) {
return $injector.instantiate(Class);
};
});
}
provider.factory = function(name, factory) {
provider.provide(name, function() {
this.$get = function($injector) {
return $injector.invoke(factory);
};
});
}
provider.value = function(name, value) {
provider.factory(name, function() {
return value;
});
};
live exemple
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() {
// In the provider function, you cannot inject any
// service or factory. This can only be done at the
// "$get" method.
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()];
}
Tous les Services sont des singletons, ils se instancié qu'une seule fois par app. Ils peuvent être de tout type, qu'elle soit primitive, littéral d'objet, la fonction, ou même une instance d'un type personnalisé.
L' value
, factory
, service
, constant
, et provider
méthodes sont tous les fournisseurs. Ils enseignent l'Injecteur comment instancier les Services.
Le plus verbeux, mais aussi la plus complète est un Fournisseur de recette. Les quatre autres recette types de Valeur, de l'Usine, de Service et de Constant sont juste syntaxique de sucre sur le dessus d'un fournisseur de recette.
- la Valeur de la Recette est le cas le plus simple, lorsque vous instanciez le Service vous-même et de fournir les instancié de la valeur de l'injecteur.
- L' Usine recette donne l'Injecteur d'une usine de la fonction qu'il appelle quand il a besoin d'instancier le service. Lorsqu'elle est appelée, l' usine de la fonction crée et retourne l'instance de service. Les dépendances du Service sont injectés les fonctions arguments. Donc, en utilisant cette recette ajoute les capacités suivantes:
- possibilité d'utiliser d'autres services (dépendances)
- l'initialisation du service
- retard/initialisation
- Le Service de la recette est presque la même que l'Usine recette, mais ici l'Injecteur appelle un constructeur avec le nouvel opérateur à la place d'une usine de fonction.
- Le Fournisseur de recette est généralement exagéré. Il ajoute encore une couche d'indirection en vous permettant de configurer la création de l'usine.
Vous devez utiliser le Fournisseur de recette que lorsque vous souhaitez exposer une API pour l'application de configuration qui doit être fait avant que le l'application démarre. C'est généralement intéressant que pour réutilisables services dont le comportement peut varier légèrement entre les des applications.
- La Constante recette est juste comme la Valeur recette, sauf qu'il vous permet de définir les services qui sont disponibles dans la config de la phase. Plus tôt que les services créés à l'aide de la Valeur de la recette. À la différence de Valeurs, ils ne peuvent être décorés à l'aide de
decorator
.
Consultez le fournisseur de docs.
Service vs fournisseur vs usine: J'essaie de garder les choses simples . Son tout sur le code JavaScript de base concept.
Tout d'abord parlons de services dans angularjs!
Ce qu'est le Service: Dans angularjs Service n'est rien, mais un singleton objet javascript qui peut stocker de l'utilité des méthodes ou des propriétés. Cet objet singleton est créé par ngApp(Angulaire de l'app) et il est partagé entre tous les contrôleurs dans les app en cours. Lorsque Angularjs instancier un objet de service, elle s'inscrit à ce service objet avec un nom de service unique. Donc, chaque fois quand nous en avons besoin pour obtenir l'instance de service, Angulaire des recherches dans le registre de ce nom de service, et elle retourne la référence à un objet de service.Maintenant, nous pouvons appeler la méthode, l'accès à des propriétés sur l'objet de service. Vous pouvez avoir question de savoir si vous pouvez aussi mettre de propriétés , de méthodes sur l'objet de l'étendue de contrôleurs! Alors, pourquoi vous avez besoin de service de l'objet? Réponses: les services sont partagés entre de multiples contrôleur de portée. Si vous mettez certaines propriétés/méthodes dans un contrôleur de la portée de l'objet , il sera disponible sur le régulateur de courant de champ. Mais lorsque vous définissez les méthodes,les propriétés d'un objet de service, il sera disponible dans le monde entier pour chaque contrôleur de la portée de l'actuel angulaire de l'app.
Donc Si il y a 3 contrôleurs de portée, que ce soit controllerA, controllerB et controllerC , tous partagent 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 fournir des méthodes différentes pour l'enregistrement d'un service. Ici, nous allons nous concentrer sur trois méthodes d'usine(..),le service(..),fournir(..);
Utilisez ce lien pour le code de référence
L'usine de la fonction:
nous pouvons définir la fonction de fabrication comme ci-dessous.
factory('serviceName',function fnFactory(){ return serviceInstance;})
Angulaire de fournir la méthode factory() qui prend une fonction JavaScript en tant que paramètre. Angulaire des appels de ce passé à la fonction fnFactory() pour la création d'une instance de service comme ci-dessous.
var serviceInstace = fnFactory();
La fonction peut définir un objet et le retour de l'objet , Angulaire simplement pour conserver cette référence d'objet à une variable qui est passé en premier argument. Tout ce que nous mettons sur cet objet , sera disponible à l'instance de service. Au lieu de retourner un objet , nous pouvons aussi le retour de la fonction, de valeurs, etc, tout ce que nous seront de retour , sera disponible à 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(){})
Sa le d'une autre manière, nous pouvons enregistrer un service. La seule différence est la façon Angulaire essayer d'instancier l'objet du service. Cette fois angulaire utilise "nouveau" mot-clé et d'appeler le constructeur de la fonction de quelque chose comme ci-dessous.
var serviceInstance = new fnServiceConstructor();
Dans la fonction constructeur, nous pouvons utiliser cette clé pour ajouter des propriétés ou des méthodes à l'objet du service. exemple:
//creating service using 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);
};
});
Fournir fonction:
Fournissez une (des) fonction est une autre façon pour la création de services. Laissez nous sommes intéressés à créer un service qui vient d'afficher des message d'accueil de l'utilisateur. Mais nous voulons aussi nous fournir un moyen de sorte que l'utilisateur peut configurer son propre message d'accueil. En termes techniques, nous voulons créer les services configurables. Comment pouvons-nous faire cela ? Il doit y avoir un moyen, de sorte que l'application qui pourrait passer leurs messages d'accueil personnalisé et Angularjs serait de le rendre disponible usine/fonction constructeur qui créent nos services instance. Dans un tel cas, fournissez une (des) fonction de faire le travail. à l'aide fournissez une (des) fonction nous pouvons créer des services configurables.
Nous pouvons créer des services configurables à l'aide de fournir la syntaxe comme indiqué ci-dessous.
/*step1:define a service */
app.provide('service',function serviceProviderConstructor(){});
/*step2:configure the service */
app.config(function configureService(serviceProvider){});
Comment le fournisseur de la syntaxe interne de travail?
1.Fournisseur objet est créé à l'aide de la fonction constructeur que nous avons défini dans notre fournissent la fonction.
var serviceProvider = new serviceProviderConstructor();
2.La fonction que nous avons passé en application.config(), est exécutée. Cela s'appelle config phase, et ici nous avons une chance de personnaliser notre service.
configureService(serviceProvider);
3.Enfin instance de service est créé par l'appel de $méthode get de fournisseur de services.
serviceInstance = serviceProvider.$get()
Exemple de code pour la création de service à l'aide de fournir 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 ?');
}
);
Résumé:
L'usine de l'utilisation d'une usine de la fonction qui retourne une instance de service. serviceInstance = fnFactory();
Service utiliser une fonction constructeur et Angulaire invoquer cette fonction constructeur à l'aide de "nouveau" mot-clé pour la création de l'instance de service. serviceInstance = new fnServiceConstructor();
Fournir définit un providerConstructor fonction, ce providerConstructor fonction définit une usine de la fonction $get . Angulaire appelle $get() pour créer l'objet du service. Fournir la syntaxe a un avantage supplémentaire de la configuration de l'objet de service avant d'être instancié. serviceInstance = $get();