angular.service vs angular.factory

Ik heb zowel angular.factory()als angular.service()gebruikt om services aan te geven; ik kan echter nergensangular.servicevinden officiële documentatie.

Wat is het verschil tussen de twee methoden?
Welke moet waarvoor worden gebruikt (ervan uitgaande dat ze verschillende dingen doen)?


Antwoord 1, autoriteit 100%

 angular.service('myService', myServiceFunction);
  angular.factory('myFactory', myFactoryFunction);

Ik had moeite om mijn hoofd rond dit concept te wikkelen totdat ik het mezelf op deze manier voorlegde:

Service: de functiedie u schrijft, wordt nieuw-ed:

 myInjectedService  <----  new myServiceFunction()

Fabriek: de functie(constructor) die u schrijft, wordt aangeroepen:

 myInjectedFactory  <---  myFactoryFunction()

Wat je daarmee doet, is aan jou, maar er zijn enkele handige patronen…

Zoals het schrijven van een service-functie om een openbare API bloot te leggen:

function myServiceFunction() {
  this.awesomeApi = function(optional) {
    // calculate some stuff
    return awesomeListOfValues;
  }
}
---------------------------------------------------------------------------------
// Injected in your controller
$scope.awesome = myInjectedService.awesomeApi();

Of een fabrieks-functie gebruiken om een openbare API beschikbaar te stellen:

function myFactoryFunction() {
  var aPrivateVariable = "yay";
  function hello() {
    return "hello mars " + aPrivateVariable;
  }
  // expose a public API
  return {
    hello: hello
  };
}
---------------------------------------------------------------------------------
// Injected in your controller
$scope.hello = myInjectedFactory.hello();

Of een fabrieksfunctie gebruiken om een constructor terug te geven:

function myFactoryFunction() {
    return function() {
        var a = 2;
        this.a2 = function() {
            return a*2;
        };
    };
}
---------------------------------------------------------------------------------
// Injected in your controller
var myShinyNewObject = new myInjectedFactory();
$scope.four = myShinyNewObject.a2();

Welke te gebruiken?…

Je kunt met beide hetzelfde bereiken. In sommige gevallen geeft de fabrieku echter wat meer flexibiliteit om een injectable te maken met een eenvoudigere syntaxis. Dat komt omdat, hoewel myInjectedService altijd een object moet zijn, myInjectedFactory een object, een functieverwijzing of welke waarde dan ook kan zijn. Als u bijvoorbeeld een service hebt geschreven om een constructor te maken (zoals in het laatste voorbeeld hierboven), zou deze als volgt moeten worden geïnstantieerd:

var myShinyNewObject = new myInjectedService.myFunction()

wat betwistbaar minder wenselijk is dan dit:

var myShinyNewObject = new myInjectedFactory();

(maar u moet op hun hoede zijn om dit type patroon in de eerste plaats te gebruiken, omdat Nieuwe -ing-objecten in uw controllers hard-to-track afhankelijkheden creëren die moeilijk te bespotten zijn voor testen. Beter Een service beheren Een verzameling objecten voor u beheren dan new()WILY-NELLY.)


Nog een ding, ze zijn allemaal singletons …

Houd er ook rekening mee dat Angular in beide gevallen helpt een singleton te beheren. Ongeacht waar of hoe vaak u uw service of functie injecteert, krijgt u dezelfde verwijzing naar hetzelfde object of de functie. (Met uitzondering van wanneer een fabriek eenvoudig een waarde retourneert als een getal of string. In dat geval krijgt u altijd dezelfde waarde, maar geen referentie.)


2, Autoriteit 25%

Simpel gezegd ..

const user = {
  firstName: 'john'
};
// Factory
const addLastNameFactory = (user, lastName) => ({
  ...user,
  lastName,
});
console.log(addLastNameFactory(user, 'doe'));
// Service
const addLastNameService = (user, lastName) => {
  user.lastName = lastName; // BAD! Mutation
  return user;
};
console.log(addLastNameService(user, 'doe'));

3, Autoriteit 19%

Hier zijn de primaire verschillen:

Services

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

Resultaat: bij het declareren van serviceName als een injecteerbaar argument krijgt u de instance van een functiedoorgegeven aan module.service.

Gebruik: kan handig zijn voor het delen van hulpprogramma’sdie handig zijn om aan te roepen door simpelweg ( )toe te voegen aan de geïnjecteerde functiereferentie. Kan ook worden uitgevoerd met injectedArg.call( this )of iets dergelijks.

Fabrieken

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

Resultaat: bij het declareren van feitnaam als een injecteerbaar argument krijgt u de waarde die wordt geretourneerd door de functiereferentieaan te roepen die is doorgegeven aan module.factory.

Gebruik: kan handig zijn voor het retourneren van een functie ‘class’die vervolgens kan worden vernieuwd om instanties te maken.

Hier is voorbeeld van het gebruik van services en fabriek. Lees meer over AngularJS Service vs Factory.

Je kunt ook de AngularJS-documentatieen soortgelijke vragen over stackoverflow verward over service versus fabriek.


Antwoord 4, autoriteit 3%

De aanwijzing zit in de naam

Services en fabrieken lijken op elkaar. Beide zullen een singleton-object opleveren dat in andere objecten kan worden geïnjecteerd, en worden daarom vaak door elkaar gebruikt.

Ze zijn bedoeld om semantisch te worden gebruikt om verschillende ontwerppatronen te implementeren.

Services zijn voor het implementeren van een servicepatroon

Een servicepatroon is een patroon waarin uw toepassing is opgedeeld in logisch consistente functionaliteitseenheden. Een voorbeeld kan een API-accessor zijn of een reeks bedrijfslogica.

Dit is vooral belangrijk in Angular, omdat Angular-modellen doorgaans slechts JSON-objecten zijn die van een server worden gehaald, en dus moeten we ergens onze bedrijfslogica plaatsen.

Hier is bijvoorbeeld een Github-service. Het weet hoe het met Github moet praten. Het kent url’s en methoden. We kunnen het in een controller injecteren, en het zal een belofte genereren en teruggeven.

(function() {
  var base = "https://api.github.com";
  angular.module('github', [])
    .service('githubService', function( $http ) {
      this.getEvents: function() {
        var url = [
          base,
          '/events',
          '?callback=JSON_CALLBACK'
        ].join('');
        return $http.jsonp(url);
      }
    });
  )();

Fabrieken implementeren een fabriekspatroon

Fabrieken daarentegen zijn bedoeld om een fabriekspatroon te implementeren. Een fabriekspatroon in één waarin we een fabrieksfunctie gebruiken om een object te genereren. Meestal gebruiken we dit voor het bouwen van modellen. Hier is een fabriek die een Author-constructor retourneert:

angular.module('user', [])
  .factory('User', function($resource) {
    var url = 'http://simple-api.herokuapp.com/api/v1/authors/:id'
    return $resource(url);
  })

We zouden dit als volgt gebruiken:

angular.module('app', ['user'])
  .controller('authorController', function($scope, User) {
    $scope.user = new User();
  })

Merk op dat fabrieken ook singletons retourneren.

Fabrieken kunnen een constructor teruggeven

Omdat een fabriek gewoon een object retourneert, kan het elk type object retourneren dat u maar wilt, inclusief een constructorfunctie, zoals we hierboven zien.

Fabrieken retourneren een voorwerp; Diensten zijn nieuwbouw

Een ander technisch verschil bevindt zich in de manier waarop diensten en fabrieken zijn samengesteld. Een servicefunctie wordt genoemd om het object te genereren. Een fabrieksfunctie wordt gebeld en zal het object retourneren.

  • Services zijn nieuwere constructeurs.
  • Fabrieken worden eenvoudigweg gebeld en retourneer een object.

Dit betekent dat we in een dienst bijdragen aan “dit” die, in het kader van een constructor, zal wijzen op het voorwerp in aanbouw. ​​

Om dit te illustreren, is hier hetzelfde eenvoudige object gemaakt met behulp van een service en een fabriek:

angular.module('app', [])
  .service('helloService', function() {
    this.sayHello = function() {
      return "Hello!";
    }
  })
  .factory('helloFactory', function() {
    return {
      sayHello: function() {
        return "Hello!";
      }
    }
  });

5, Autoriteit 2%

Alle antwoorden hier lijken te zijn in de buurt van Service en Factory, en dat is geldig sindsdien waar werd gevraagd. Maar het is ook belangrijk om in gedachten te houden dat er verschillende anderen zijn, waaronder provider(), value()en constant().

De sleutel om te onthouden is dat elk een speciaal geval van de ander is. Elk speciaal geval in de ketting waarmee u hetzelfde kunt doen met minder code. Iedereen heeft ook wat extra beperking.

Om te beslissen wanneer u moet gebruiken, welke u gewoon ziet welke u toestaat om te doen wat u wilt in minder code. Hier is een afbeelding die illustreert hoe vergelijkbaar ze zijn:

Voor een compleet stapsgewijze overzicht en een snelle referentie van wanneer je ze moet gebruiken, kun je de blogpost bezoeken waar ik deze afbeelding vandaan heb:

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


Antwoord 6, autoriteit 2%

app.factory(‘fn’, fn) vs. app.service(‘fn’,fn)

Bouw

Bij fabrieken zal Angular de functie aanroepen om het resultaat te krijgen. Het is het resultaat dat in de cache wordt opgeslagen en wordt geïnjecteerd.

//factory
 var obj = fn();
 return obj;

Bij services zal Angular de constructorfunctie aanroepen door newaan te roepen. De geconstrueerde functie wordt in de cache opgeslagen en geïnjecteerd.

 //service
  var obj = new fn();
  return obj;

Implementatie

Fabrieken retourneren meestal een object letterlijk omdat de geretourneerde waarde iswat wordt geïnjecteerd in controllers, run-blokken, richtlijnen, enz.

 app.factory('fn', function(){
         var foo = 0;
         var bar = 0;
         function setFoo(val) {
               foo = val;
         }
         function setBar (val){
               bar = val;
         }
         return {
                setFoo: setFoo,
                serBar: setBar
         }
  });

Servicefuncties retourneren doorgaans niets. In plaats daarvan voeren ze initialisatie- en onthullingsfuncties uit. Functies kunnen ook verwijzen naar ‘dit’ omdat het is geconstrueerd met ‘nieuw’.

app.service('fn', function () {
         var foo = 0;
         var bar = 0;
         this.setFoo = function (val) {
               foo = val;
         }
         this.setBar = function (val){
               bar = val;
         }
});

Conclusie

Als het gaat om het gebruik van fabrieken of services, lijken ze allebei erg op elkaar. Ze worden geïnjecteerd in een controller, richtlijnen, run-blok, enz., en worden op vrijwel dezelfde manier in clientcode gebruikt. Ze zijn ook beide singletons – wat betekent dat dezelfde instantie wordt gedeeld tussen alle plaatsen waar de service/fabriek wordt geïnjecteerd.

Dus wat zou je voorkeur hebben? Een van beide – ze lijken zo op elkaar dat de verschillen triviaal zijn. Als je de een boven de ander kiest, wees je er dan van bewust hoe ze zijn opgebouwd, zodat je ze op de juiste manier kunt implementeren.


Antwoord 7

Ik heb wat tijd besteed aan het uitzoeken van het verschil.

En ik denk dat de fabrieksfunctie het modulepatroon gebruikt en de servicefunctie het standaard javascript-constructorpatroon.


Antwoord 8

Het fabriekspatroon is flexibeler omdat het zowel functies en waarden als objecten kan retourneren.

Er is niet veel zin in het servicepatroon IMHO, want alles wat het doet, kun je net zo gemakkelijk doen met een fabriek. De uitzonderingen kunnen zijn:

  • Als u om de een of andere reden geeft om het gedeclareerde type van uw geïnstantieerde service, als u het servicepatroon gebruikt, is uw constructor het type van de nieuwe service.
  • Als je al een constructorfunctie hebt die je elders gebruikt en die je ook als een service wilt gebruiken (hoewel waarschijnlijk niet veel nut heeft als je er iets in wilt injecteren!).

Ongetwijfeld is het servicepatroon een iets leukeremanier om een nieuw object te maken vanuit syntaxisoogpunt, maar het is ook duurder om te instantiëren. Anderen hebben aangegeven dat angular “new” gebruikt om de service te maken, maar dit is niet helemaal waar – het is niet in staat om dat te doen omdat elke serviceconstructor een ander aantal parameters heeft. Wat hoekig eigenlijk doet, is het fabriekspatroon intern gebruiken om uw constructorfunctie in te pakken. Dan doet het een slimme gok om de “nieuwe” operator van javascript te simuleren, door uw constructor aan te roepen met een variabel aantal injecteerbare argumenten – maar u kunt deze stap overslaan als u het fabriekspatroon rechtstreeks gebruikt, dus de efficiëntie van uw code zeer lichtjes verhogen.

Other episodes