javascript - AngularJS: Fabrică și Serviciu?


EDIT Jan 2016: Deoarece acest lucru încă atrage atenția. De când am întrebat asta, am finalizat câteva proiecte AngularJS și pentru acestea am folosit în mare parte factory, am construit un obiect și am returnat obiectul la final. Afirmațiile mele de mai jos sunt încă adevărate, totuși.

EDITARE : Cred că în sfârșit înțeleg diferența principală dintre cele două și am un exemplu de cod pentru a demonstra. De asemenea, cred că această întrebare este diferită de cea propusă ca duplicat. Duplicatul spune că serviciul nu poate fi instanțiat, dar dacă îl configurezi așa cum am demonstrat mai jos, de fapt se poate. Un serviciu poate fi configurat să fie exact la fel ca o fabrică. Voi oferi, de asemenea, cod care arată unde eșuează fabrica în comparație cu serviciul, ceea ce niciun alt răspuns nu pare să facă.

Dacă configurez VaderService astfel (adică ca serviciu):

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

module.service('VaderService', function() {
    this.speak = function (name) {
        return 'Join the dark side ' + name;
    }
});

Apoi, în controllerul meu pot să fac asta:

module.controller('StarWarsController', function($scope, VaderService) {
    $scope.luke = VaderService.speak('luke');   
});

Cu serviciul, VaderService injectat în controller este instanțiat, astfel încât pot pur și simplu să apelez VaderService.speak, însă, dacă schimb VaderService în module.factory, codul din controller nu va mai funcționa, și aceasta este principala diferență. Cu factory, VaderService injectat în controller nu este instanțiat, motiv pentru care trebuie să returnezi un obiect atunci când configurezi un factory (vezi exemplul meu din întrebare).

Cu toate acestea, poți configura un serviciu în exact același mod în care poți configura o fabrică (adică să returneze un obiect) și serviciul se comportă exact ca o fabrică

Având aceste informații, nu văd niciun motiv să folosesc fabrica în locul serviciului, serviciul poate face tot ce poate fabrica și mai mult.

Întrebarea originală mai jos.

Știu că acest lucru a fost întrebat de nenumărate ori, dar nu pot vedea nicio diferență funcțională între fabrici și servicii. Am citit acest tutorial: http://blogs.clevertech.biz/startupblog/angularjs-factory-service-provider

Și se pare că oferă o explicație destul de bună, totuși, am configurat aplicația mea astfel:

index.html

<!DOCTYPE html>
<html>
    <head>
    <title>My App</title>
    <script src="lib/angular/angular.js"></script>
    <script type="text/javascript" src="js/controllers.js"></script>
    <script type="text/javascript" src="js/VaderService.js"></script>
    <script type="text/javascript" src="js/app.js"></script>
    </head>

    <body ng-app="MyApp"> 
        <table ng-controller="StarWarsController">
            <tbody>
            <tr><td>{{luke}}</td></tr>
            </tbody>
        </table>
    </body>
</html>

app.js:

angular.module('MyApp', [
  'MyApp.services',
  'MyApp.controllers'
]);

controllers.js:

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

module.controller('StarWarsController', function($scope, VaderService) {
    var luke = new VaderService('luke');
    $scope.luke = luke.speak();
});

VaderService.js

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

module.factory('VaderService', function() {
    var VaderClass = function(padawan) {
        this.name = padawan;
        this.speak = function () {
            return 'Join the dark side ' + this.name;
        }
    }

    return VaderClass;
});

Atunci când încarc index.html văd „Alătură-te părții întunecate, Luke”, grozav. Exact cum mă așteptam. Totuși, dacă schimb VaderService.js la aceasta (observați module.service în loc de module.factory):

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

module.service('VaderService', function() {
    var VaderClass = function(padawan) {
        this.name = padawan;
        this.speak = function () {
            return 'Join the dark side ' + this.name;
        }
    }

    return VaderClass;
});

Apoi reîncarcă index.html (m-am asigurat că am golit cache-ul și am făcut o reîncărcare completă). Funcționează exact la fel cum funcționa cu module.factory. Deci care este diferența funcțională reală între cele două??

Răspuns #1

Serviciu vs Fabrica

Diferența dintre fabrică și serviciu este exact ca diferența dintre o funcție și un obiect

Furnizor de fabrică

  • Ne oferă valoarea de returnare a funcției, adică. Creezi doar un obiect, adaugi proprietăți la acesta, apoi returnezi același obiect. Când treci acest serviciu în controller-ul tău, acele proprietăți ale obiectului vor fi acum disponibile în acel controller prin intermediul fabricii tale. (Scenariu ipotetic)

  • Singleton și va fi creat doar o singură dată

  • Componente reutilizabile

  • Fabricile sunt o modalitate excelentă de a comunica între controlere, cum ar fi partajarea datelor.

  • Poate folosi alte dependențe

  • De obicei folosit atunci când instanța serviciului necesită o logică complexă de creare

  • Nu poate fi injectat în funcția .config().

  • Utilizat pentru servicii neconfigurabile

  • Dacă folosești un obiect, ai putea folosi furnizorul de tip fabrică.

  • Sintaxă: module.factory('numeFabrica', funcție);

Furnizor de servicii

  • Ne oferă instanța unei funcții (obiect) - tocmai ai instanțiat cu cuvântul cheie 'new' și vei adăuga proprietăți la 'this', iar serviciul va returna 'this'. Când treci serviciul în controlerul tău, acele proprietăți de pe 'this' vor fi acum disponibile în controlerul respectiv prin serviciul tău. (Scenariu ipotetic)

  • Singleton și va fi creat doar o dată

  • Componente reutilizabile

  • Serviciile sunt utilizate pentru comunicarea între controllere pentru a partaja date

  • Poți adăuga proprietăți și funcții unui obiect serviciu folosind cuvântul cheie this

  • Dependențele sunt injectate ca argumente ale constructorului

  • Folosit pentru logica simplă de creare

  • Nu poate fi injectat în funcția .config().

  • Dacă folosești o clasă, ai putea folosi furnizorul de servicii

  • Sintaxă: module.service('serviceName', function);

Exemplu Demo

În exemplul de mai jos am definit MyService și MyFactory. Observați cum în .service am creat metodele serviciului folosind this.methodname. În .factory am creat un obiect factory și i-am asignat metodele.

AngularJS .service

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

    this.method1 = function() {
            //..method1 logic
        }

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

AngularJS .factory

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

    var factory = {}; 

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

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

    return factory;
});

Aruncă și o privire la aceste lucruri frumoase

Confuz în legătură cu serviciul versus fabrică

AngularJS Fabrică, Serviciu și Furnizor

Angular.js: serviciu vs furnizor vs fabrică?

Răspunsul #2

Factory și Service sunt doar un înveliș al unui provider.

Fabrică

Factory poate returna orice poate fi un class (funcție constructor), instanță a unei clase, string, număr sau boolean. Dacă returnezi o funcție constructor, o poți instanția în controller-ul tău.

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

  // any logic here..

  // Return any thing. Here it is object
  return {
    name: 'Joe'
  }
}

Serviciu

Serviciul nu trebuie să returneze nimic. Dar trebuie să atribui totul în variabila this. Pentru că serviciul va crea o instanță implicit și o va folosi ca obiect de bază.

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

  // any logic here..

  this.name = 'Joe';
}

Codul actual AngularJS din spatele serviciului

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

Este doar un înveliș în jurul factory. Dacă returnezi ceva din service, atunci se va comporta ca Factory.

IMPORTANT: Rezultatul returnat de la Factory și Service va fi memorat în cache și același rezultat va fi returnat pentru toate controllerele.

Când ar trebui să le folosesc?

Factory este de obicei preferată în toate cazurile. Poate fi folosită atunci când ai o funcție constructor care trebuie instanțiată în diferite controllere.

Service este un fel de obiect Singleton. Obiectul returnat de Service va fi același pentru toate controllerele. Poate fi utilizat atunci când dorești să ai un singur obiect pentru întreaga aplicație. Ex: Detaliile utilizatorului autentificat.

Pentru mai multă înțelegere, citiți

http://iffycan.blogspot.in/2013/05/angular-service-or-factory.html

http://viralpatel.net/blogs/angularjs-service-factory-tutorial/