Vraag AngularJS: Service versus aanbieder versus fabriek


Wat zijn de verschillen tussen een Service, Provider en Factory in AngularJS?


3163
2018-03-27 17:59


oorsprong


antwoorden:


Van de AngularJS-mailinglijst die ik kreeg een geweldige thread dat verklaart service vs vs vs provider en hun injectiegebruik. De antwoorden samenstellen:

Diensten

Syntaxis: module.service( 'serviceName', function ); 
Resultaat: Bij het declareren van serviceName als een injecteerbaar argument u krijgt een exemplaar van de functie. Met andere woorden  new FunctionYouPassedToService().

fabrieken

Syntaxis: module.factory( 'factoryName', function ); 
Resultaat: bij het declareren van factoryName als een injecteerbaar argument dat u krijgt de waarde die wordt geretourneerd door het oproepen van de functiereferentie die is doorgegeven aan module.factory.

providers

Syntaxis: module.provider( 'providerName', function ); 
Resultaat: bij het declareren van providerName als een injecteerbaar argument je zal worden voorzien  (new ProviderFunction()).$get(). De constructorfunctie wordt geïnstantieerd voordat de $ get-methode wordt aangeroepen - ProviderFunction is de functie referentie doorgegeven aan module.provider.

Providers hebben het voordeel dat ze kunnen worden geconfigureerd tijdens de moduleconfiguratiefase.

Zien hier voor de opgegeven code.

Hier is een geweldige verdere uitleg door Misko:

provide.value('a', 123);

function Controller(a) {
  expect(a).toEqual(123);
}

In dit geval retourneert de injector eenvoudig de waarde zoals deze is. Maar wat als u de waarde wilt berekenen? Gebruik vervolgens een fabriek

provide.factory('b', function(a) {
  return a*2;
});

function Controller(b) {
  expect(b).toEqual(246);
}

Zo factory is een functie die verantwoordelijk is voor het creëren van de waarde. Merk op dat de fabrieksfunctie andere afhankelijkheden kan vragen.

Maar wat als je meer OO wilt zijn en een klasse hebt die Greeter heet?

function Greeter(a) {
  this.greet = function() {
    return 'Hello ' + a;
  }
}

Om vervolgens te instantiëren zou je moeten schrijven

provide.factory('greeter', function(a) {
  return new Greeter(a);
});

Dan kunnen we in deze controller om 'greeter' vragen

function Controller(greeter) {
  expect(greeter instanceof Greeter).toBe(true);
  expect(greeter.greet()).toEqual('Hello 123');
}

Maar dat is veel te veelomvattend. Een kortere manier om dit te schrijven zou zijn provider.service('greeter', Greeter);

Maar wat als we de. Wilden configureren Greeter klasse voor de injectie? Dan kunnen we schrijven

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);
  };
});

Dan kunnen we dit doen:

angular.module('abc', []).config(function(greeter2Provider) {
  greeter2Provider.setSalutation('Halo');
});

function Controller(greeter2) {
  expect(greeter2.greet()).toEqual('Halo 123');
}

Als een kanttekening, service, factory, en value zijn allemaal afgeleid van provider.

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;
  });
};

2800
2017-07-30 10:20



JS Fiddle Demo

"Hallo wereld" voorbeeld met 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() {

    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 src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="MyCtrl">
    {{hellos}}
</div>
</body>


796
2018-05-15 15:53



TL; DR 

1) Wanneer u een gebruikt Fabriek je maakt een object, voegt er eigenschappen aan toe en retourneert dan hetzelfde object. Wanneer u deze fabriek doorgeeft aan uw controller, zijn die eigenschappen van het object nu beschikbaar in die controller via uw fabriek.

app.controller(‘myFactoryCtrl’, function($scope, myFactory){
  $scope.artist = myFactory.getArtist();
});

app.factory(‘myFactory’, function(){
  var _artist = ‘Shakira’;
  var service = {};

  service.getArtist = function(){
    return _artist;
  }

  return service;
});


2) Wanneer je gebruikt Service, AngularJS brengt het achter de schermen in beeld met het 'nieuwe' sleutelwoord. Daarom voegt u eigenschappen toe aan 'dit' en de service retourneert 'dit'. Wanneer u de service doorgeeft aan uw controller, zijn die eigenschappen op 'this' nu beschikbaar op die controller via uw service.

app.controller(‘myServiceCtrl’, function($scope, myService){
  $scope.artist = myService.getArtist();
});

app.service(‘myService’, function(){
  var _artist = ‘Nelly’;
  this.getArtist = function(){
    return _artist;
  }
});



3)  providers zijn de enige services die u kunt doorgeven aan uw .config () -functie. Gebruik een provider als u de module-brede configuratie voor uw serviceobject wilt bieden voordat u deze beschikbaar stelt.

app.controller(‘myProvider’, function($scope, myProvider){
  $scope.artist = myProvider.getArtist();
  $scope.data.thingFromConfig = myProvider.thingOnConfig;
});

app.provider(‘myProvider’, function(){
 //Only the next two lines are available in the app.config()
 this._artist = ‘’;
 this.thingFromConfig = ‘’;
  this.$get = function(){
    var that = this;
    return {
      getArtist: function(){
        return that._artist;
      },
      thingOnConfig: that.thingFromConfig
    }
  }
});

app.config(function(myProviderProvider){
  myProviderProvider.thingFromConfig = ‘This was set in config’;
});



Niet TL; DR

1) Fabriek 
Fabrieken zijn de meest populaire manier om een ​​service te maken en te configureren. Er is echt niet veel meer dan wat de TL; DR zei. U maakt gewoon een object, voegt er eigenschappen aan toe en retourneert vervolgens hetzelfde object. Wanneer u vervolgens de fabriek doorgeeft aan uw controller, zijn die eigenschappen van het object nu beschikbaar in die controller via uw fabriek. Een uitgebreider voorbeeld is hieronder.

app.factory(‘myFactory’, function(){
  var service = {};
  return service;
});

Welke eigenschappen we dan ook aan 'service' hechten, zal voor ons beschikbaar zijn wanneer we 'myFactory' doorgeven aan onze controller.

Laten we nu wat 'privé'variabelen toevoegen aan onze callback-functie. Deze zullen niet direct toegankelijk zijn vanaf de controller, maar uiteindelijk zullen we wat getter / setter-methoden instellen op 'service' om deze 'privé' variabelen te kunnen veranderen wanneer nodig.

app.factory(‘myFactory’, function($http, $q){
  var service = {};
  var baseUrl = ‘https://itunes.apple.com/search?term=’;
  var _artist = ‘’;
  var _finalUrl = ‘’;

  var makeUrl = function(){
   _artist = _artist.split(‘ ‘).join(‘+’);
    _finalUrl = baseUrl + _artist + ‘&callback=JSON_CALLBACK’;
    return _finalUrl
  }

  return service;
});

Hier ziet u dat we die variabelen / functie niet koppelen aan 'service'. We zijn ze eenvoudig aan het maken om ze later te gebruiken of te wijzigen.

  • baseUrl is de basis-URL die de iTunes API vereist
  • _artist is de artiest die we willen opzoeken
  • _finalUrl is de laatste en volledig gebouwde URL waarnaar we naar iTunes bellen
  • makeUrl is een functie die onze iTunes friendly URL zal creëren en retourneren.

Nu onze helper / privévariabelen en -functie aanwezig zijn, laten we wat eigenschappen toevoegen aan het 'service'-object. Wat we ook op 'service' zetten, kan direct worden gebruikt binnen elke controller waar we 'myFactory' doorgeven.

We gaan setArtist en getArtist-methoden maken die de artiest eenvoudig terugbrengen of instellen. We gaan ook een methode maken die de iTunes API zal oproepen met onze gemaakte URL. Deze methode zal een belofte teruggeven die zal worden uitgevoerd zodra de gegevens zijn teruggekeerd van de iTunes API. Als je nog niet veel ervaring hebt gehad met het gebruiken van beloften in AngularJS, raad ik je ten zeerste aan een diepe duik te nemen.

beneden setArtist accepteert een artiest en stelt u in staat de artiest in te stellen. getArtist geeft de artiest terug. callItunes eerste roept makeUrl () aan om de URL te bouwen die we zullen gebruiken met ons $ http-verzoek. Vervolgens wordt een object met de belofte ingesteld, wordt een $ http-verzoek met onze uiteindelijke URL gemaakt en vervolgens, omdat $ http een belofte retourneert, kunnen we .success of .error na ons verzoek callen. We lossen onze belofte vervolgens op met de iTunes-gegevens, of we verwerpen het met de melding 'Er was een fout'.

app.factory('myFactory', function($http, $q){
  var service = {};
  var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  var makeUrl = function(){
    _artist = _artist.split(' ').join('+');
    _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
    return _finalUrl;
  }

  service.setArtist = function(artist){
    _artist = artist;
  }

  service.getArtist = function(){
    return _artist;
  }

  service.callItunes = function(){
    makeUrl();
    var deferred = $q.defer();
    $http({
      method: 'JSONP',
      url: _finalUrl
    }).success(function(data){
      deferred.resolve(data);
    }).error(function(){
      deferred.reject('There was an error')
    })
    return deferred.promise;
  }

  return service;
});

Nu is onze fabriek voltooid. We kunnen nu 'myFactory' in elke controller injecteren en we kunnen dan onze methodes bellen die we hebben gekoppeld aan ons service-object (setArtist, getArtist en callItunes).

app.controller('myFactoryCtrl', function($scope, myFactory){
  $scope.data = {};
  $scope.updateArtist = function(){
    myFactory.setArtist($scope.data.artist);
  };

  $scope.submitArtist = function(){
    myFactory.callItunes()
      .then(function(data){
        $scope.data.artistData = data;
      }, function(data){
        alert(data);
      })
  }
});

In de controller hierboven injecteren we in de 'myFactory'-service. Vervolgens stellen we eigenschappen in op ons $ scope-object met gegevens van 'myFactory'. De enige lastige code hierboven is als je nog nooit eerder met beloften hebt afgerekend. Omdat callItunes een belofte teruggeeft, kunnen we de methode .then () gebruiken en $ scope.data.artistData alleen instellen als onze belofte is vervuld met de iTunes-gegevens. Je zult merken dat onze controller erg 'dun' is (dit is een goede codeermethode). Al onze logische en persistente gegevens bevinden zich in onze service, niet in onze controller.

2) Service 
Misschien is het grootste dat je moet weten als je te maken hebt met het maken van een Service, dat het wordt geïnstantieerd met het 'nieuwe' sleutelwoord. Voor jou JavaScript goeroes zou dit je een grote hint in de aard van de code moeten geven. Voor degenen onder u met een beperkte achtergrond in JavaScript of voor degenen die niet bekend zijn met wat het 'nieuwe' sleutelwoord eigenlijk doet, laten we wat JavaScript-grondbeginselen bekijken die ons uiteindelijk zullen helpen bij het begrijpen van de aard van een Service.

Om echt de wijzigingen te zien die optreden wanneer u een functie aanroept met het 'nieuwe' sleutelwoord, laten we een functie maken en deze aanroepen met het 'nieuwe' sleutelwoord, laten we dan laten zien wat de tolk doet wanneer hij het 'nieuwe' sleutelwoord ziet. De eindresultaten zullen beide hetzelfde zijn.

Laten we eerst onze Constructor maken.

var Person = function(name, age){
  this.name = name;
  this.age = age;
}

Dit is een typische JavaScript-constructorfunctie. Wanneer we nu de Person-functie gebruiken met het 'nieuwe' sleutelwoord, zal 'dit' gebonden zijn aan het nieuw gecreëerde object.

Laten we nu een methode toevoegen aan het prototype van onze Persoon, zodat deze beschikbaar is voor elk exemplaar van onze Persoonsklasse.

Person.prototype.sayName = function(){
  alert(‘My name is ‘ + this.name);
}

Omdat we de functie sayName gebruiken voor het prototype, kan elke instantie van Person de functie sayName in de juiste volgorde bellen om de naam van die instantie te activeren.

Nu we onze Person Constructor-functie en onze sayName-functie op zijn prototype hebben, kunnen we eigenlijk een instantie van Person maken en vervolgens de sayName-functie aanroepen.

var tyler = new Person(‘Tyler’, 23);
tyler.sayName(); //alerts ‘My name is Tyler’

Dus alles bij elkaar de code voor het maken van een Person-constructor, het toevoegen van een functie aan het prototype, het maken van een Person-instantie en het vervolgens aanroepen van de functie op zijn prototype ziet er als volgt uit.

var Person = function(name, age){
  this.name = name;
  this.age = age;
}
Person.prototype.sayName = function(){
  alert(‘My name is ‘ + this.name);
}
var tyler = new Person(‘Tyler’, 23);
tyler.sayName(); //alerts ‘My name is Tyler’

Laten we nu eens kijken naar wat er werkelijk gebeurt als u het 'nieuwe' trefwoord in JavaScript gebruikt. Het eerste wat je zou moeten opmerken is dat na het gebruik van 'nieuw' in ons voorbeeld, we een methode (sayName) op 'tyler' kunnen oproepen alsof het een object is - dat is omdat het is. Dus eerst weten we dat onze Person-constructor een object retourneert, of we dat in de code kunnen zien of niet. Ten tweede weten we dat omdat onze sayName-functie zich op het prototype bevindt en niet rechtstreeks op het Person-exemplaar, het object dat de Person-functie retourneert, moet delegeren naar zijn prototype bij mislukte lookups. In meer eenvoudige bewoordingen, als we tyler.sayName () noemen, zegt de interpreter "OK, ik ga kijken naar het 'tyler'-object dat we zojuist hebben gemaakt, zoek de sayName-functie op en noem het. Wacht even, ik zie het hier niet - alles wat ik zie is naam en leeftijd, laat me het prototype controleren. Yup, het lijkt erop dat het op het prototype staat, laat me het noemen. ".

Hieronder staat de code voor hoe u kunt bedenken wat het 'nieuwe' zoekwoord eigenlijk doet in JavaScript. Het is in feite een codevoorbeeld van de bovenstaande paragraaf. Ik heb de 'interpreter view' of de manier waarop de interpreter de code in notities ziet geplaatst.

var Person = function(name, age){
  //The below line creates an object(obj) that will delegate to the person’s prototype on failed lookups.
  //var obj = Object.create(Person.prototype);

  //The line directly below this sets ‘this’ to the newly created object
  //this = obj;

  this.name = name;
  this.age = age;

  //return this;
}

Nu deze kennis van wat het 'nieuwe' zoekwoord echt doet in JavaScript, moet het maken van een service in AngularJS gemakkelijker te begrijpen zijn.

Het belangrijkste om te begrijpen bij het maken van een Service is te weten dat Services worden geïnstantieerd met het 'nieuwe' sleutelwoord. Door die kennis te combineren met onze voorbeelden hierboven, zou u nu moeten erkennen dat u uw eigenschappen en methoden direct aan 'dit' koppelt, die vervolgens uit de Service zelf worden geretourneerd. Laten we dit in actie bekijken.

In tegenstelling tot wat we aanvankelijk met het Factory-voorbeeld deden, hoeven we geen object te maken en vervolgens dat object te retourneren, omdat we, zoals zo vaak eerder is vermeld, het 'nieuwe' sleutelwoord hebben gebruikt, zodat de interpreter dat object maakt, laat het delegeren naar het is een prototype en retourneer het voor ons zonder dat we het werk hoeven te doen.

Laten we eerst onze 'privé'- en helperfunctie maken. Dit zou heel bekend moeten voorkomen, omdat we precies hetzelfde deden met onze fabriek. Ik zal niet uitleggen wat elke regel hier doet, omdat ik dat deed in het fabrieksvoorbeeld, als je in de war bent, lees dan het fabrieksvoorbeeld opnieuw.

app.service('myService', function($http, $q){
  var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  var makeUrl = function(){
    _artist = _artist.split(' ').join('+');
    _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
    return _finalUrl;
  }
});

Nu voegen we al onze methoden die beschikbaar zijn in onze controller toe aan 'dit'.

app.service('myService', function($http, $q){
  var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  var makeUrl = function(){
    _artist = _artist.split(' ').join('+');
    _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
    return _finalUrl;
  }

  this.setArtist = function(artist){
    _artist = artist;
  }

  this.getArtist = function(){
    return _artist;
  }

  this.callItunes = function(){
    makeUrl();
    var deferred = $q.defer();
    $http({
      method: 'JSONP',
      url: _finalUrl
    }).success(function(data){
      deferred.resolve(data);
    }).error(function(){
      deferred.reject('There was an error')
    })
    return deferred.promise;
  }

});

Nu zijn, net als in onze fabriek, setArtist, getArtist en callItunes beschikbaar in elke controller waar we myService doorgeven. Hier is de myService-controller (die bijna precies hetzelfde is als onze fabriekscontroller).

app.controller('myServiceCtrl', function($scope, myService){
  $scope.data = {};
  $scope.updateArtist = function(){
    myService.setArtist($scope.data.artist);
  };

  $scope.submitArtist = function(){
    myService.callItunes()
      .then(function(data){
        $scope.data.artistData = data;
      }, function(data){
        alert(data);
      })
  }
});

Zoals ik al eerder zei, als je echt begrijpt wat 'nieuw' is, zijn services bijna identiek aan fabrieken in AngularJS.

3) Aanbieder

Het grootste ding om te onthouden over Providers is dat ze de enige service zijn die u kunt doorgeven aan het app.config-gedeelte van uw applicatie. Dit is van enorm belang als u een deel van uw service-object moet wijzigen voordat het overal elders in uw toepassing beschikbaar is. Hoewel vergelijkbaar met Services / Fabrieken, zijn er enkele verschillen die we zullen bespreken.

Eerst hebben we onze provider op dezelfde manier opgezet als bij onze service en fabriek. De onderstaande variabelen zijn onze 'privé'- en helperfunctie.

app.provider('myProvider', function(){
   var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  //Going to set this property on the config function below.
  this.thingFromConfig = ‘’;

  var makeUrl = function(){
    _artist = _artist.split(' ').join('+');
    _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
    return _finalUrl;
  }
}

* Nogmaals, als een deel van de bovenstaande code verwarrend is, bekijk dan de Factory-sectie, waar ik uitleg wat het allemaal doet, meer details.

U kunt denken dat leveranciers drie secties hebben. De eerste sectie is de 'privé' variabelen / functies die later zullen worden aangepast / ingesteld (hierboven weergegeven). De tweede sectie is de variabelen / functies die beschikbaar zullen zijn in uw app.config-functie en kunnen daarom worden gewijzigd voordat ze ergens anders beschikbaar zijn (zie ook hierboven). Het is belangrijk om te weten dat deze variabelen moeten worden toegevoegd aan het sleutelwoord 'dit'. In ons voorbeeld is alleen 'thingFromConfig' beschikbaar om te wijzigen in de app.config. Het derde gedeelte (hieronder weergegeven) is alle variabelen / functies die beschikbaar zullen zijn in uw controller wanneer u in de service 'myProvider' doorgeeft aan die specifieke controller.

Wanneer u een service met Provider maakt, zijn de enige eigenschappen / methoden die beschikbaar zijn in uw controller die eigenschappen / methoden die worden geretourneerd uit de functie $ get (). De onderstaande code zet $ op 'dit' (waarvan we weten dat deze uiteindelijk van die functie zal worden teruggegeven). Nu krijgt die $ get-functie alle methoden / eigenschappen die we beschikbaar willen hebben in de controller. Hier is een codevoorbeeld.

this.$get = function($http, $q){
    return {
      callItunes: function(){
        makeUrl();
        var deferred = $q.defer();
        $http({
          method: 'JSONP',
          url: _finalUrl
        }).success(function(data){
          deferred.resolve(data);
        }).error(function(){
          deferred.reject('There was an error')
        })
        return deferred.promise;
      },
      setArtist: function(artist){
        _artist = artist;
      },
      getArtist: function(){
        return _artist;
      },
      thingOnConfig: this.thingFromConfig
    }
  }

Nu ziet de volledige Provider-code er zo uit

app.provider('myProvider', function(){
  var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  //Going to set this property on the config function below
  this.thingFromConfig = '';

  var makeUrl = function(){
    _artist = _artist.split(' ').join('+');
    _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
    return _finalUrl;
  }

  this.$get = function($http, $q){
    return {
      callItunes: function(){
        makeUrl();
        var deferred = $q.defer();
        $http({
          method: 'JSONP',
          url: _finalUrl
        }).success(function(data){
          deferred.resolve(data);
        }).error(function(){
          deferred.reject('There was an error')
        })
        return deferred.promise;
      },
      setArtist: function(artist){
        _artist = artist;
      },
      getArtist: function(){
        return _artist;
      },
      thingOnConfig: this.thingFromConfig
    }
  }
});

Nu zijn, net als in onze fabriek en Service, setArtist, getArtist en callItunes beschikbaar in elke controller waar we myProvider doorheen voeren. Hier is de myProvider-controller (die bijna precies hetzelfde is als onze fabriek / service-controller).

app.controller('myProviderCtrl', function($scope, myProvider){
  $scope.data = {};
  $scope.updateArtist = function(){
    myProvider.setArtist($scope.data.artist);
  };

  $scope.submitArtist = function(){
    myProvider.callItunes()
      .then(function(data){
        $scope.data.artistData = data;
      }, function(data){
        alert(data);
      })
  }

  $scope.data.thingFromConfig = myProvider.thingOnConfig;
});

Zoals eerder vermeld, is het hele punt van het maken van een service met Provider om enkele variabelen te kunnen wijzigen via de app.config-functie voordat het laatste object wordt doorgegeven aan de rest van de toepassing. Laten we daar een voorbeeld van zien.

app.config(function(myProviderProvider){
  //Providers are the only service you can pass into app.config
  myProviderProvider.thingFromConfig = 'This sentence was set in app.config. Providers are the only service that can be passed into config. Check out the code to see how it works';
});

Nu kun je zien hoe 'thingFromConfig' in onze provider als een lege string is, maar als dat in de DOM verschijnt, is het 'Deze zin is ingesteld ...'.


618
2017-12-24 13:15



Alle services zijn eenlingen; ze worden eenmaal per app geïnstantieerd. Ze kunnen zijn van welk type dan ook, of het nu een primitieve, objectuele, functie of zelfs een instantie van een aangepast type is.

De value, factory, service, constant, en provider methoden zijn allemaal providers. Ze leren de Injector hoe de Services te instantiëren.

De meest uitgebreide, maar ook de meest uitgebreide is een aanbieder   recept. De de resterende vier recept types - Waarde, Fabriek, Service en   Constant - zijn gewoon syntactische suiker bovenop een receptenrecept.

  • De Waarde recept is het eenvoudigste geval, waarbij u zelf de service start en de geïnstantieerde waarde naar de injector.
  • De Fabrieksrecept geeft de Injector een fabrieksfunctie die hij oproept wanneer hij de service moet starten. Indien opgeroepen, de fabrieksfunctie maakt en retourneert de service-instance. De afhankelijkheden van de Service worden geïnjecteerd als de argumenten van de functies. Dus het gebruik van dit recept voegt de volgende mogelijkheden toe:
    • Mogelijkheid om andere services te gebruiken (afhankelijkheden)
    • Service-initialisatie
    • Vertraagde / luie initialisatie
  • De Service recept is bijna hetzelfde als het Factory-recept, maar hier roept de Injector a bouwer met de nieuwe operator in plaats van een fabrieksfunctie.
  • De Provider recept is gewoonlijk overkill. Er wordt nog een laag indirecte richting toegevoegd, zodat u het maken van de fabriek kunt configureren.

U moet het Provider-recept alleen gebruiken als u een API wilt ontmaskeren   voor toepassingsbrede configuratie die moet worden gemaakt vóór de   toepassing start. Dit is meestal alleen interessant voor herbruikbare   services waarvan het gedrag enigszins moet verschillen   toepassingen.


506
2018-02-01 12:58



Inzicht in AngularJS Factory, Service en Provider

Al deze worden gebruikt om herbruikbare singleton-objecten te delen. Het helpt om herbruikbare code te delen in uw app / verschillende componenten / modules.

Van Docs Service / Factory:

  • Lui geconstateerd - Angular stelt alleen een service / fabriek in het leven wanneer een applicatiecomponent ervan afhankelijk is.
  • singletons - Elk onderdeel   afhankelijk van een service krijgt een verwijzing naar de enkele instantie   gegenereerd door de servicefabriek.

Fabriek

Een fabriek is een functie waarbij u logica kunt bewerken / toevoegen voordat u een object maakt, waarna het nieuw gemaakte object wordt geretourneerd.

app.factory('MyFactory', function() {
    var serviceObj = {};
    //creating an object with methods/functions or variables
    serviceObj.myFunction = function() {
        //TO DO:
    };
    //return that object
    return serviceObj;
});

Gebruik

Het kan gewoon een verzameling functies zijn zoals een klas. Daarom kan het in verschillende controllers worden geïnstantieerd wanneer u het in uw controller / fabriek / richtlijn-functies injecteert. Het wordt maar één keer per app geïnstantieerd.

Service

Kijk eenvoudig naar de services en denk na over het array-prototype. Een service is een functie die een nieuw object maakt met het 'nieuwe' sleutelwoord. U kunt eigenschappen en functies aan een service-object toevoegen met behulp van de thistrefwoord. In tegenstelling tot een fabriek, retourneert het niets (het retourneert een object dat methoden / eigenschappen bevat).

app.service('MyService', function() {
    //directly binding events to this context
    this.myServiceFunction = function() {
        //TO DO:
    };
});

Gebruik

Gebruik het wanneer u een enkel object in de hele applicatie wilt delen. Bijvoorbeeld geauthenticeerde gebruikersgegevens, gedeelde methoden / gegevens, hulpprogramma's enz.

leverancier

Een provider wordt gebruikt om een ​​configureerbaar serviceobject te maken. U kunt de service-instelling configureren vanuit de config-functie. Het retourneert een waarde met behulp van de $get() functie. De $get functie wordt uitgevoerd in de run-fase in hoekig.

app.provider('configurableService', function() {
    var name = '';
    //this method can be be available at configuration time inside app.config.
    this.setName = function(newName) {
        name = newName;
    };
    this.$get = function() {
        var getName = function() {
             return name;
        };
        return {
            getName: getName //exposed object to where it gets injected.
        };
    };
});

Gebruik

Wanneer u voor uw service-object module-configuratie moet geven voordat u het beschikbaar maakt, bijvoorbeeld stel dat u uw API-URL wilt instellen op basis van uw omgeving, zoals dev, stage of prod

NOTITIE 

Alleen provider is beschikbaar in configuratiefase van hoekig, terwijl   service en fabriek zijn dat niet.

Ik hoop dat dit je begrip heeft opgelost Fabriek, service en provider.


221
2017-11-14 06:25



Voor mij kwam de openbaring toen ik me realiseerde dat ze allemaal op dezelfde manier werken: door iets te doen een keer, de waarde opslaan die ze krijgen en dan ophoesten dezelfde opgeslagen waarde wanneer ernaar wordt verwezen afhankelijkheid injectie.

Zeggen dat we:

app.factory('a', fn);
app.service('b', fn);
app.provider('c', fn);

Het verschil tussen de drie is dat:

  1. aopgeslagen waarde komt van hardlopen fn.
  2. bDe opgeslagen waarde is afkomstig van newing fn.
  3. cOpgeslagen waarde komt van het eerst ophalen van een exemplaar newing fnen dan een $get methode van de instantie.

Wat betekent dat er iets is zoals een cache-object in AngularJS, waarvan de waarde van elke injectie slechts eenmaal wordt toegekend, wanneer ze de eerste keer zijn geïnjecteerd en wanneer:

cache.a = fn()
cache.b = new fn()
cache.c = (new fn()).$get()

Dit is waarom we gebruiken this in services en definieer a this.$get in providers.


190
2017-07-22 11:39



Service vs aanbieder versus fabriek:

Ik probeer het eenvoudig te houden. Het gaat allemaal om basis JavaScript-concept.

Laten we het eerst eens over hebben Diensten in AngularJS!

Wat is Service: In AngularJS, Service is niets anders dan een enig JavaScript-object dat enkele bruikbare methoden of eigenschappen kan opslaan. Dit singleton-object is gemaakt op basis van ngApp (hoekige app) en wordt gedeeld door alle controllers binnen de huidige app. Wanneer Angularjs een serviceobject instantieert, registreert dit dit service-object met een unieke servicenaam. Telkens wanneer we een service-exemplaar nodig hebben, doorzoekt Angular het register voor deze servicenaam en wordt de verwijzing naar het serviceobject geretourneerd. Zodanig dat we de methode, toegangseigenschappen, enz. Op het serviceobject kunnen aanroepen. U kunt zich afvragen of u ook eigenschappen, methoden op het scope-object van controllers kunt plaatsen! Dus waarom hebt u service-objecten nodig? Antwoorden is: services worden gedeeld over meerdere controllerbereik. Als u enkele eigenschappen / methoden in het scope-object van een controller plaatst, is deze alleen beschikbaar voor het huidige bereik. Maar wanneer u methoden, eigenschappen op serviceobjecten definieert, zal deze globaal beschikbaar zijn en toegankelijk zijn in het bereik van elke controller door die service te injecteren.

Dus als er drie controllers zijn, laat het dan controllerA, controllerB en controllerC zijn, dan zullen ze allemaal hetzelfde service-exemplaar delen.

<div ng-controller='controllerA'>
    <!-- controllerA scope -->
</div>
<div ng-controller='controllerB'>
    <!-- controllerB scope -->
</div>
<div ng-controller='controllerC'>
    <!-- controllerC scope -->
</div>

Hoe een service te maken?

AngularJS biedt verschillende methoden om een ​​service te registreren. Hier zullen we ons concentreren op drie methoden fabriek (..), service (..), provider (..);

Gebruik deze link voor codeverwijzing

Fabriek functie:

We kunnen een fabrieksfunctie definiëren zoals hieronder.

factory('serviceName',function fnFactory(){ return serviceInstance;})

AngularJS biedt 'factory (' serviceName ', fnFactory)' methode die twee parameters, serviceNaam en een JavaScript-functie vereist. Angular creëert een service-instantie door de functie aan te roepen fnFactory () zoals hieronder.

var serviceInstace = fnFactory();

De doorgegeven functie kan een object definiëren en dat object retourneren. AngularJS slaat deze objectreferentie eenvoudig op in een variabele die als eerste argument wordt doorgegeven. Alles wat wordt geretourneerd door fnFactory is gebonden aan serviceInstance. In plaats van een object te retourneren, kunnen we ook de functie, waarden enz. Retourneren. Wat we ook zullen teruggeven, is beschikbaar voor een service-exemplaar.

Voorbeeld:

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;
});

Service Functie:

service('serviceName',function fnServiceConstructor(){})

Het is een andere manier, we kunnen een service registreren. Het enige verschil is de manier waarop AngularJS het serviceobject probeert te instantiëren. Deze keer maakt hoekig gebruik van 'nieuw' sleutelwoord en roept de constructorfunctie iets als hieronder.

var serviceInstance = new fnServiceConstructor();

In de constructorfunctie kunnen we 'dit' sleutelwoord gebruiken om eigenschappen / methoden aan het serviceobject toe te voegen. voorbeeld:

//Creating a service using the 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);
  };
});

Provider functie:

De functie Provider () is een andere manier om services te maken. Laten we geïnteresseerd zijn om een ​​service te maken die slechts een begroetingsbericht voor de gebruiker weergeeft. Maar we willen ook een functionaliteit bieden zodat de gebruiker zijn eigen begroetingsbericht kan instellen. In technische termen willen we configureerbare services maken. Hoe kunnen we dit doen? Er moet een manier zijn, zodat de app hun aangepaste begroetingsberichten kan doorgeven en Angularjs deze beschikbaar maakt voor de functie fabriek / constructor die onze services-instantie maakt. In zo'n geval doet de functie provider () het werk. met de functie provider () kunnen we configureerbare services maken.

We kunnen configureerbare services maken met behulp van de syntaxis van de provider, zoals hieronder weergegeven.

/*step1:define a service */
app.provider('service',function serviceProviderConstructor(){});

/*step2:configure the service */
app.config(function configureService(serviceProvider){});

Hoe werkt de syntaxis van de provider intern?

1.Provider-object wordt gemaakt met de constructorfunctie die we hebben gedefinieerd in onze providorfunctie.

var serviceProvider = new serviceProviderConstructor();

2.De functie die we hebben doorgegeven in app.config (), wordt uitgevoerd. Dit wordt de configuratiefase genoemd en hier hebben we een kans om onze service aan te passen.

configureService(serviceProvider);

3. Eindservice-exemplaar wordt gemaakt door $ get-methode van serviceProvider aan te roepen.

serviceInstance = serviceProvider.$get()

Voorbeeldcode voor het maken van services met behulp van de syntaxis:

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 ?');
  }
);

Werkende demo

Overzicht:


Fabriek gebruik een fabrieksfunctie die een service-exemplaar retourneert. serviceInstance = fnFactory ();

Service gebruik een constructorfunctie en Angular voer deze constructorfunctie in met behulp van 'nieuw' sleutelwoord voor het maken van de service-instantie. serviceInstance = nieuwe fnServiceConstructor ();

leverancier definieert een providerConstructor-functie, deze providerConstructor-functie definieert een fabrieksfunctie $ get . Hoekig roept $ get () aan om het serviceobject te maken. Providersyntaxis heeft een extra voordeel bij het configureren van het serviceobject voordat het wordt geïnstantieerd. serviceInstance = $ get ();


133
2017-11-19 13:36



Zoals meerdere mensen hier correct hebben aangegeven, zijn een fabriek, een leverancier, een service en zelfs een waarde en een constante versies van hetzelfde. Je kunt het meer algemene ontleden provider in allemaal. Zoals zo:

enter image description here

Hier is het artikel waar deze afbeelding van is:

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


79
2017-08-02 05:37



Fabriek

U geeft AngularJS een functie, AngularJS zal cachen en de retourwaarde injecteren wanneer de fabriek wordt gevraagd.

Voorbeeld:

app.factory('factory', function() {
    var name = '';
    // Return value **is** the object that will be injected
    return {
        name: name;
    }
})

Gebruik:

app.controller('ctrl', function($scope, factory) {
     $scope.name = factory.name;
});

Service

Je geeft AngularJS een functie, AngularJS belt nieuwe om het te instantiëren. Het is het exemplaar dat door AngularJS wordt gemaakt en dat in de cache wordt geplaatst en wordt ingespoten wanneer om de service wordt gevraagd. Sinds nieuwe werd gebruikt om de service, het sleutelwoord, te instantiëren deze is geldig en verwijst naar het exemplaar.

Voorbeeld:

app.service('service', function() {
     var name = '';
     this.setName = function(newName) {
         name = newName;
     }
     this.getName = function() {
         return name;
     }
});

Gebruik:

app.controller('ctrl', function($scope, service) {
   $scope.name = service.getName();
});

leverancier

Je geeft AngularJS een functie, en AngularJS zal het noemen $get functie. Het is de retourwaarde van de $get functie die wordt gecached en geïnjecteerd wanneer de service wordt aangevraagd.

Met providers kunt u de provider configureren voor AngularJS noemt de $get methode om het injecteerbare te krijgen.

Voorbeeld:

app.provider('provider', function() {
     var name = '';
     this.setName = function(newName) {
          name = newName;
     }
     this.$get = function() {
         return {
            name: name
         }
     }
})

Gebruik (als injecteerbaar in een controller)

app.controller('ctrl', function($scope, provider) {
    $scope.name = provider.name;
});

Gebruik (eerder configureren van de provider $get is geroepen om het injecteerbare te maken)

app.config(function(providerProvider) {
    providerProvider.setName('John');
});

62
2018-05-19 19:53