web-dev-qa-db-fra.com

Confus à propos de Service vs Factory

Si je comprends bien, lorsque je rentre dans une usine, je retourne un objet qui est injecté dans un contrôleur. Lorsque je suis à l'intérieur d'un service, je traite l'objet avec this sans rien retourner.

Je pensais qu'un service était toujours un singleton et qu'un nouvel objet d'usine était injecté dans chaque contrôleur. Cependant, il s'avère qu'un objet d'usine est aussi un singleton?

Exemple de code pour démontrer:

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

factories.factory('User', function () {
  return {
    first: 'John',
    last: 'Doe'
  };
});

app.controller('ACtrl', function($scope, User) {
  $scope.user = User;
});

app.controller('BCtrl', function($scope, User) {
  $scope.user = User;
});

Lors du changement de user.first dans ACtrl, il s'avère que user.first dans BCtrl est également modifié, par ex. User est un singleton?

Mon hypothèse était qu'une nouvelle instance a été injectée dans un contrôleur avec une usine?

615
JvdBerg

Tous les angular services sont des singletons :

Docs (voir Services en tant que singletons ): https://docs.angularjs.org/guide/services

Enfin, il est important de réaliser que tous les services Angular sont des singletons d’application. Cela signifie qu'il n'y a qu'une seule instance d'un service donné par injecteur.

La différence entre le service et l’usine est la suivante:

app.service('myService', function() {

  // service is just a constructor function
  // that will be called with 'new'

  this.sayHello = function(name) {
     return "Hi " + name + "!";
  };
});

app.factory('myFactory', function() {

  // factory returns an object
  // you can run some code before

  return {
    sayHello : function(name) {
      return "Hi " + name + "!";
    }
  }
});

Regardez cette présentation à propos de $ fournir: http://slides.wesalvaro.com/20121113/#/

Ces diapositives ont été utilisées dans l'une des réunions AngularJs: http://blog.angularjs.org/2012/11/more-angularjs-meetup-videos.html

598
matys84pl

Pour moi, la révélation a été faite quand je me suis rendu compte qu'ils fonctionnaient tous de la même manière: en exécutant quelque chose ne fois, en stockant la valeur qu'ils obtenaient, puis en toussant cette même valeur stockée quand référencé 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. La valeur stockée de a provient de l'exécution de fn, autrement dit: fn()
  2. La valeur stockée de b provient de newing fn, autrement dit: new fn()
  3. La valeur stockée de c provient du premier processus d’obtention d’une instance par newing fn, puis de l’exécution de la méthode $get de l’instance.

c’est-à-dire qu’il s’agit d’un objet cache dans angular 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 this dans les services et définissons un this.$get dans les fournisseurs.

J'espère que cela t'aides.

380
Lucia

exemple en direct

"bonjour le monde" exemple

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()];
}​
96
EpokK

Il existe également un moyen de renvoyer une fonction constructeur afin que vous puissiez renvoyer newable dans les usines, comme cette:

function MyObjectWithParam($rootScope, name) {
  this.$rootScope = $rootScope;
  this.name = name;
}
MyObjectWithParam.prototype.getText = function () {
  return this.name;
};

App.factory('MyObjectWithParam', function ($injector) {
  return function(name) { 
    return $injector.instantiate(MyObjectWithParam,{ name: name });
  };
}); 

Vous pouvez donc le faire dans un contrôleur utilisant MyObjectWithParam:

var obj = new MyObjectWithParam("hello"),

Voir ici l'exemple complet:
http://plnkr.co/edit/GKnhIN?p=preview

Et voici les pages du groupe Google, où il a été discuté:
https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/b8hdPskxZXsJ

57
JustGoscha

Voici les principales différences:

Prestations de service

Syntaxe: module.service( 'serviceName', function );

Résultat: lors de la déclaration de serviceName en tant qu'argument injectable, l'instance d'une fonction sera transmise à module.service.

Utilisation: Peut être utile pour partager des fonctions utilitaires qu'il est utile d'invoquer en ajoutant simplement () à la référence de fonction injectée. Peut également être exécuté avec injectedArg.call( this ) ou similaire.

Des usines

Syntaxe: module.factory( 'factoryName', function );

Résultat: lors de la déclaration de factoryName en tant qu'argument injectable, vous recevrez la valeur renvoyée en appelant la référence de fonction transmise à module.factory.

Utilisation: Peut être utile pour renvoyer une fonction 'class' qui peut ensuite être créée pour créer des instances.

Vérifiez également documentation AngularJS et une question similaire sur stackoverflow confus sur le service vs l'usine .

Voici exemple utilisant services et factory . En savoir plus sur service AngularJS vs usine .

51
Manish Chhabra

En ajoutant à la première réponse, je pense que .service () est destiné aux personnes qui ont écrit leur code dans un style plus orienté objet (C #/Java) (en utilisant ce mot clé et en instanciant un objet via la fonction prototype/constructeur).

Factory est destiné aux développeurs qui écrivent du code qui est plus naturel au style de code javascript/fonctionnel.

Jetez un coup d'œil au code source de la méthode .service et .factory dans angular.js - en interne, ils appellent tous la méthode du fournisseur:

  function provider(name, provider_) {
    if (isFunction(provider_)) {
      provider_ = providerInjector.instantiate(provider_);
    }
    if (!provider_.$get) {
      throw Error('Provider ' + name + ' must define $get factory method.');
    }
    return providerCache[name + providerSuffix] = provider_;
  }

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

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

Très simplement:

.service - la fonction enregistrée sera invoquée en tant que constructeur (alias 'newed')

.factory - la fonction enregistrée sera appelée comme une fonction simple

Les deux sont invoqués une fois, ce qui donne un objet singleton injecté dans d'autres composants de votre application.

25
bingles

Tous les fournisseurs fonctionnent de la même manière. Les différentes méthodes service, factory, provider permettent de réaliser la même chose avec moins de code.

P.S. Il y a aussi value et constant.

Chaque cas particulier de la chaîne commençant par provider et se terminant par value présente une limitation supplémentaire. Donc, pour décider entre eux, vous devez vous demander ce qui vous permet d'accomplir ce que vous voulez avec moins de code.

Voici une image qui vous montre ce que je veux dire:

enter image description here

Vous pouvez consulter un guide de référence et de ventilation sur le blog où j'ai obtenu cette image:

http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/

20
Luis Perez

Voici quelques exemples supplémentaires de services contre usines qui peuvent être utiles pour voir la différence entre eux. En gros, un service a "nouveau ..." appelé, il est déjà instancié. Une usine n'est pas instanciée automatiquement.

Exemples de base

Retourne un objet de classe qui a une seule méthode

Voici un service qui a une seule méthode:

angular.service('Hello', function () {
  this.sayHello = function () { /* ... */ };
});

Voici une fabrique qui retourne un objet avec une méthode:

angular.factory('ClassFactory', function () {
  return {
    sayHello: function () { /* ... */ }
  };
});

Renvoyer une valeur

Une usine qui renvoie une liste de nombres:

angular.factory('NumberListFactory', function () {
  return [1, 2, 3, 4, 5];
});

console.log(NumberListFactory);

Un service qui renvoie une liste de nombres:

angular.service('NumberLister', function () {
  this.numbers = [1, 2, 3, 4, 5];
});

console.log(NumberLister.numbers);

La sortie dans les deux cas est la même, la liste des nombres.

Exemples avancés

"Classe" variables utilisant des usines

Dans cet exemple, nous définissons un CounterFactory, il incrémente ou décrémente un compteur et vous pouvez obtenir le nombre actuel ou obtenir le nombre d'objets CounterFactory créés:

angular.factory('CounterFactory', function () {
  var number_of_counter_factories = 0; // class variable

  return function () {
    var count = 0; // instance variable
    number_of_counter_factories += 1; // increment the class variable

    // this method accesses the class variable
    this.getNumberOfCounterFactories = function () {
      return number_of_counter_factories;
    };

    this.inc = function () {
      count += 1;
    };
    this.dec = function () {
      count -= 1;
    };
    this.getCount = function () {
      return count;
    };
  }

})

Nous utilisons le CounterFactory pour créer plusieurs compteurs. Nous pouvons accéder à la variable de classe pour voir combien de compteurs ont été créés:

var people_counter;
var places_counter;

people_counter = new CounterFactory();
console.log('people', people_counter.getCount());
people_counter.inc();
console.log('people', people_counter.getCount());

console.log('counters', people_counter.getNumberOfCounterFactories());

places_counter = new CounterFactory();
console.log('places', places_counter.getCount());

console.log('counters', people_counter.getNumberOfCounterFactories());
console.log('counters', places_counter.getNumberOfCounterFactories());

La sortie de ce code est:

people 0
people 1
counters 1
places 0
counters 2
counters 2
13
Rudolf Olah

“Usine” et “Service” sont différentes manières de faire DI (injection de dépendance) en angulaire.

Donc, lorsque nous définissons DI en utilisant "service", comme indiqué dans le code ci-dessous. Cela crée une nouvelle instance GLOBAL de l’objet "Logger" et l’injecte dans la fonction.

app.service("Logger", Logger); // Injects a global object

Lorsque vous définissez DI en utilisant une "usine", cela ne crée pas d'instance. Il ne fait que transmettre la méthode, puis le consommateur doit en interne faire des appels à la fabrique pour les instances d'objet.

app.factory("Customerfactory", CreateCustomer);

Ci-dessous une image simple qui montre visuellement comment le processus DI pour "Service" est différent de "Usine".

enter image description here

L'usine doit être utilisée lorsque nous voulons créer différents types d'objets en fonction de scénarios. Par exemple, en fonction du scénario, nous souhaitons créer un objet "Client" simple, ou "Client" avec un objet "Adresse" ou "Client" avec un objet "Téléphone". Voici une explication détaillée de ce paragraphe

Le service doit être utilisé lorsque nous avons des fonctions utilitaires ou partagées à injecter telles que utilitaire, enregistreur, gestionnaire d'erreurs, etc.

13

Service style: (( probablement le plus simple ) renvoie la fonction réelle: utile pour le partage de fonctions utilitaires qui sont utiles pour invoquer simplement en ajoutant () à la référence de fonction injectée.

Un service dans AngularJS est un objet JavaScript singleton qui contient un ensemble de fonctions.

var myModule = angular.module("myModule", []);

myModule.value  ("myValue"  , "12345");

function MyService(myValue) {
    this.doIt = function() {
        console.log("done: " + myValue;
    }
}

myModule.service("myService", MyService);
myModule.controller("MyController", function($scope, myService) {

    myService.doIt();

});

Factory style: ( plus impliqué mais plus sophistiqué ) renvoie la valeur de retour de la fonction: instancie un objet comme nouvel objet () en Java.

Factory est une fonction qui crée des valeurs. Lorsqu'un service, un contrôleur, etc. a besoin d'une valeur injectée par une usine, celle-ci crée la valeur à la demande. Une fois créée, la valeur est réutilisée pour tous les services, contrôleurs, etc. qui en ont besoin.

var myModule = angular.module("myModule", []);

myModule.value("numberValue", 999);

myModule.factory("myFactory", function(numberValue) {
    return "a value: " + numberValue;
})  
myModule.controller("MyController", function($scope, myFactory) {

    console.log(myFactory);

});

Fournisseur style: ( complet, version configurable ) renvoie le résultat de la fonction $ get de la fonction: Configurable.

Les fournisseurs dans AngularJS sont la forme d’usine la plus flexible que vous puissiez créer. Vous enregistrez un fournisseur avec un module, comme vous le faites avec un service ou une fabrique, sauf que vous utilisez plutôt la fonction provider ().

var myModule = angular.module("myModule", []);

myModule.provider("mySecondService", function() {
    var provider = {};
    var config   = { configParam : "default" };

    provider.doConfig = function(configParam) {
        config.configParam = configParam;
    }

    provider.$get = function() {
        var service = {};

        service.doService = function() {
            console.log("mySecondService: " + config.configParam);
        }

        return service;
    }

    return provider;
});

myModule.config( function( mySecondServiceProvider ) {
    mySecondServiceProvider.doConfig("new config param");
});

myModule.controller("MyController", function($scope, mySecondService) {

    $scope.whenButtonClicked = function() {
        mySecondService.doIt();
    }

});

src jenkov

<!DOCTYPE html>
    <html ng-app="app">
    <head>
        <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.min.js"></script>
        <meta charset=utf-8 />
        <title>JS Bin</title>
    </head>
    <body ng-controller="MyCtrl">
        {{serviceOutput}}
        <br/><br/>
        {{factoryOutput}}
        <br/><br/>
        {{providerOutput}}
    
        <script>
    
                var app = angular.module( 'app', [] );
    
                var MyFunc = function() {
    
                        this.name = "default name";
    
                        this.$get = function() {
                                this.name = "new name"
                                return "Hello from MyFunc.$get(). this.name = " + this.name;
                        };
    
                        return "Hello from MyFunc(). this.name = " + this.name;
                };
    
                // returns the actual function
                app.service( 'myService', MyFunc );
    
                // returns the function's return value
                app.factory( 'myFactory', MyFunc );
    
                // returns the output of the function's $get function
                app.provider( 'myProv', MyFunc );
    
                function MyCtrl( $scope, myService, myFactory, myProv ) {
    
                        $scope.serviceOutput = "myService = " + myService;
                        $scope.factoryOutput = "myFactory = " + myFactory;
                        $scope.providerOutput = "myProvider = " + myProv;
    
                }
    
        </script>
    
    </body>
    </html>

jsbin

<!DOCTYPE html>
<html ng-app="myApp">
<head>
        <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.min.js"></script>
        <meta charset=utf-8 />
        <title>JS Bin</title>
</head>
<body>
<div ng-controller="MyCtrl">
    {{hellos}}
</div>
        <script>

        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>

</body>
</html>

jsfiddle

8
Premraj

La différence fondamentale est que fournisseur permet de définir des valeurs de fonction primitive (non-objets), de tableau ou de rappel dans la variable déclarée en usine. Ainsi, si un objet est renvoyé, il doit être explicitement déclaré et renvoyé. .

D'autre part, un service ne peut être utilisé que pour définir la variable de service déclarée sur un objet. Ainsi, nous pouvons éviter la création et le retour explicites des objets, tout en permettant l'utilisation du this mot-clé.

Ou en quelques mots "fournisseur est une forme plus générique alors que service est limité aux objets uniquement".

2
yoel halb

C'est ainsi que j'ai compris la différence entre eux en termes de modèles de conception:

Service: Retourne un type, qui sera créé pour créer un objet de ce type. Si Java analogie est utilisée, Service renvoie un définition de classe Java.

Factory: Retourne un objet concret pouvant être utilisé immédiatement. Dans Java Analogie, une fabrique renvoie un objet Java.

La partie qui confond souvent les gens (y compris moi-même) est que lorsque vous injectez un service ou une fabrique dans votre code, ils peuvent être utilisés de la même manière. Ce que vous obtenez dans votre code est un objet concret que vous pouvez immédiatement invoquer. Ce qui signifie que, dans le cas du service, angular appelle "nouveau" dans la déclaration de service pour votre compte. Je pense que c'est un concept compliqué.

2
Hisham

Nous pouvons définir un service comme ceci:

app.service('MyService', function () {
   this.sayHello = function () {
      console.log('hello');
   };
});

.service() est une méthode de notre module qui prend un nom et une fonction qui définit le service. Assez simple. Une fois définis, nous pouvons injecter et utiliser ce service dans d’autres composants, tels que des contrôleurs, des directives et des filtres, comme ceci:

Maintenant la même chose qu'une usine:

app.factory('MyService', function () {
    return {
       sayHello: function () {
           console.log('hello');
       }
    }
});

Encore une fois, .factory() est une méthode de notre module qui prend également un nom et une fonction, qui définit la fabrique. Nous pouvons injecter et utiliser cette chose de la même manière que nous l’avons fait avec le service. Maintenant, quelle est la différence ici?

Vous constaterez peut-être qu'au lieu de travailler avec cela en usine, nous retournons un littéral d'objet. Pourquoi donc? Il s’avère qu’un service est une fonction constructeur alors qu’une usine ne l’est pas. Quelque part au fond de ce monde Angular, il y a ce code qui appelle Object.create () avec la fonction constructeur du service, quand il est instancié. Cependant, une fonction fabrique n'est en réalité qu'une fonction appelée, c'est pourquoi nous devons renvoyer explicitement un objet.

2
Rajat-Systematix

Service AngularJS vs Usine

module.service( 'serviceName', function );

module.factory( 'factoryName', function );

Lorsque vous déclarez serviceName en tant qu'argument injectable, vous obtenez une instance de la fonction. En d'autres termes new FunctionYouPassedToService(). Cette instance d'objet devient l'objet de service que AngularJS enregistre et injecte ultérieurement à d'autres services / controllers si nécessaire.

Lorsque vous déclarez factoryName en tant qu'argument injectable, vous recevrez la valeur renvoyée en appelant la référence de fonction transmise à module.factory.

Dans l'exemple ci-dessous, nous définissons MyService de deux manières différentes. Notez comment, dans .service, nous créons des méthodes de service en utilisant this.methodname. Dans .factory, nous avons créé un objet usine et lui avons attribué les méthodes.

AngularJS .service

module.service('MyService', function() {
    this.method1 = function() {
            //..
        }

    this.method2 = function() {
            //..
        }
});

AngularJS .factory

module.factory('MyService', function() {

    var factory = {}; 

    factory.method1 = function() {
            //..
        }

    factory.method2 = function() {
            //..
        }

    return factory;
});
2
Alex Jolig

C'est ce qui m'a aidé à comprendre la différence, grâce à un article de Pascal Precht sur le blog.

Un service est une méthode sur un module qui prend un nom et une fonction qui définit le service. Vous pouvez injecter et utiliser ce service dans d'autres composants, tels que des contrôleurs, des directives et des filtres. Une fabrique est une méthode sur un module et prend également un nom et une fonction qui définit la fabrique. Nous pouvons également injecter et utiliser le même traitement que nous avons utilisé avec le service.

Les objets créés avec new utilisent la valeur de la propriété prototype de leur fonction constructeur en tant que prototype. J'ai donc trouvé le code Angular qui appelle Object.create (), qui, à mon avis, est la fonction constructeur du service instancié. Cependant, une fonction d'usine n'est en réalité qu'une fonction appelée; c'est pourquoi nous devons renvoyer un littéral d'objet pour l'usine.

Voici le code angular 1.5 que j'ai trouvé pour factory:

var needsRecurse = false;
    var destination = copyType(source);

    if (destination === undefined) {
      destination = isArray(source) ? [] : Object.create(getPrototypeOf(source));
      needsRecurse = true;
    }

Extrait de code source angulaire pour la fonction factory ():

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

Il prend le nom et la fonction factory transmise et renvoie un fournisseur portant le même nom, qui possède une méthode $ get, qui est notre fonction factory. Chaque fois que vous demandez à l'injecteur une dépendance spécifique, il demande au fournisseur correspondant une instance de ce service en appelant la méthode $ get (). C’est pourquoi $ get () est requis lors de la création de fournisseurs.

Voici le code angular 1.5 pour le service.

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

Il s'avère que lorsque nous appelons service (), il appelle réellement factory ()! Cependant, il ne fait pas que transmettre notre fonction de constructeur de service à l’usine en l’état. Il passe également une fonction qui demande à l'injecteur d'instancier un objet par le constructeur donné.

En d'autres termes, si nous injectons MyService quelque part, le code contient ce qui suit:

MyServiceProvider.$get(); // return the instance of the service

Pour le reformuler, un service appelle une fabrique, qui est une méthode $ get () sur le fournisseur correspondant. De plus, $ injector.instantiate () est la méthode qui appelle finalement Object.create () avec la fonction constructeur. C’est pourquoi nous utilisons "ceci" dans les services.

Pour ES5, peu importe ce que nous utilisons: service () ou factory (), il s’agit toujours d’une usine appelée qui crée un fournisseur pour notre service.

Vous pouvez aussi faire exactement la même chose avec les services. Un service est une fonction constructeur qui ne nous empêche toutefois pas de renvoyer des littéraux d’objet. Ainsi, nous pouvons prendre notre code de service et l'écrire de manière à ce qu'il fasse exactement la même chose que notre usine. En d'autres termes, vous pouvez écrire un service en tant qu'usine pour renvoyer un objet.

Pourquoi la plupart des gens recommandent-ils d'utiliser les usines plutôt que les services? C’est la meilleure réponse que j’ai vue qui soit tirée du livre de Pawel Kozlowski: Maîtriser le développement d’applications Web avec AngularJS.

La méthode factory est le moyen le plus courant d’obtenir des objets dans le système d’injection de dépendance AngularJS. Il est très flexible et peut contenir une logique de création sophistiquée. Comme les fabriques sont des fonctions standard, nous pouvons également tirer parti d’un nouveau champ lexical pour simuler des variables "privées". Ceci est très utile car nous pouvons cacher les détails d’implémentation d’un service donné. "

1
James Drinkard
  • Avec le sine, vous créez réellement un objet à l'intérieur du sine et le retournez.
  • Avec le service, vous avez juste un fonction standard qui utilise le mot clé this pour définir la fonction.
  • Avec le fournisseur, vous définissez un $get et vous pouvez l’utiliser pour obtenir l’objet qui renvoie les données.
1
Oskar

Dans AngularJS, il existe trois manières de gérer la logique métier: (inspiré du cours Coursera AngularJS de Yaakov), qui sont:

  1. Un service
  2. Usine
  3. Fournisseur

Ici, nous allons seulement parler de Service vs Factory

SERVICE:

Syntaxe:

app.js

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

 ServiceExampleController.$inject = ['NameOfTheService'] //very important as this 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>

Les principales caractéristiques du service:

  1. Lazily Instancié : Si le service n'est pas injecté, il ne sera jamais instancié. Donc, pour l'utiliser, vous devrez l'injecter dans un module.

  2. Singleton : s'il est injecté à plusieurs modules, tous auront accès à une seule instance particulière. C'est pourquoi, il est très pratique de partager des données entre différents contrôleurs.

USINE

Parlons maintenant de l'usine dans AngularJS

Regardons 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. Ces types de services suivent le modèle de conception d'usine. L'usine peut être considérée comme un lieu central qui crée de nouveaux objets ou méthodes.

  2. Cela ne produit pas seulement un singleton, mais aussi des services personnalisables.

  3. La méthode .service() est une fabrique qui produit toujours le même type de service, à savoir un singleton. Il n'y a pas de moyen facile de configurer son comportement. Cette méthode .service() est généralement utilisée comme raccourci pour quelque chose qui ne nécessite aucune configuration.

1
Pritam Banerjee

Pour une explication simple et brève, voir https://stackoverflow.com/a/26924234/581197 .

Pour une explication détaillée, voir https://stackoverflow.com/a/15666049/581197 .

Également à partir de la documentation angularJs: enter image description here

1
Ishpreet

Ce serait la meilleure et courte réponse pour comprendre Service Vs Factory Vs Provider

Source : https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/HuZsOsMvKv4J

Voici ce que ben dit avec une démo http://jsbin.com/ohamub/1/edit?html,output

"Il y a des commentaires dans le code qui illustrent les principales différences, mais je vais les développer un peu. Comme note, je suis en train de comprendre ce que je pense, donc si je dis quelque chose qui ne va pas, merci de me le faire savoir.

Services

Syntaxe : module.service ('serviceName', fonction);

Résultat : lors de la déclaration de serviceName en tant qu'argument injectable, la référence de fonction réelle transmise à module.service sera fournie.

Usage : Peut être utile pour le partage de fonctions utilitaires qu'il est utile d'invoquer en ajoutant simplement () à la référence de fonction injectée. Peut également être exécuté avec injectedArg.call (this) ou similaire.

Usines

Syntaxe : module.factory ('nom d'usine', fonction);

Résultat : Lors de la déclaration de factoryName en tant qu'argument injectable, la valeur renvoyée par la référence de la fonction transmise à module.factory sera fournie.

Usage : Peut être utile pour renvoyer une fonction 'classe' pouvant ensuite être créée pour créer des instances.

Fournisseurs

Syntaxe : module.provider ('nom du fournisseur', fonction);

Résultat : Lors de la déclaration de providerName en tant qu'argument injectable, vous recevrez la valeur renvoyée en appelant la méthode $ get de la référence de fonction transmise au module. fournisseur.

Usage : Peut être utile pour renvoyer une fonction 'classe' qui peut ensuite être créée pour créer des instances mais qui nécessite une sorte de configuration avant d'être injectée. . Peut-être utile pour les classes réutilisables dans plusieurs projets? Encore un peu flou sur celui-ci. "Ben

Vous pouvez comprendre la différence avec cette analogie - Considérez la différence entre une fonction normale qui renverra une valeur et une fonction constructeur qui sera instanciée à l’aide d’un nouveau mot-clé. un objet) alors que créer un service revient à créer une fonction constructeur (classe OO) dont on peut créer une instance en utilisant un nouveau mot clé. La seule chose à noter est que lorsque nous utilisons la méthode Service pour créer des services, elle en crée automatiquement une instance à l'aide du mécanisme d'injection de dépendance pris en charge par AngularJS.

0
Sourabh Ranka