Kann jemand für Anfänger den Unterschied zwischen Service, Factory und Provider in AngularJS klar erklären?


Antwort 1:

AngularJS: Unterschied zwischen Service und Provider und Factory

Wenn Sie danach suchen, liegt es wahrscheinlich daran, dass Sie herausfinden möchten, welches das richtige für Sie ist. Oder weil Sie auf die drei gestoßen sind und versuchen, den Unterschied festzustellen, weil sie ähnlich erscheinen.

Wenn Sie denken, dass sie ähnlich sind, haben Sie Recht. Sie sind sehr ähnlich. In der Tat sind sie alle dasselbe.

Sie sind alle Anbieter. Die Fabrik und der Service sind nur Sonderfälle des Anbieters, aber Sie können alles erreichen, was Sie wollen, indem Sie nur den Anbieter verwenden. Ich werde Ihnen zeigen.

Der Provider

Wir werden einen Anbieter erstellen, der einen Wert zurückgibt und diesen Wert einfach anzeigt. Sie würden dies tun:

var mod = angle.module ("MyModule", []); mod.provider ("myProvider", function () {this. $ get = function () {return "My Value";};}); mod.controller ("MyController", Funktion (myProvider) {console.log ("MyController - myProvider:" + myProvider);}); KONSOLENAUSGABE MyController - myProvider: Mein Wert

Ein funktionierendes interaktives Beispiel finden Sie unter: JS Fiddle.

Dort können Sie also mit einem „Anbieter“ im Kern einen Wert „bereitstellen“. Dieser Wert könnte alles sein. In diesem Fall handelt es sich um eine Zeichenfolge mit dem Wert "Mein Wert", die jedoch leicht eine Funktion oder ein Objekt sein kann.

Beachten Sie in weiteren Codebeispielen, dass ich das ausschließen werde Tag und die Definition des Mods, um die Code-Auszüge kurz und auf den Punkt zu bringen.

Angular erhält den Wert nur einmal

Beachten Sie, dass Angular den Wert nur einmal "erhält", unabhängig davon, wie oft der Provider injiziert wird. Das heißt, es ruft $ get () nur einmal auf, speichert den von $ get () bereitgestellten Wert und gibt Ihnen jedes Mal denselben gespeicherten Wert.

Um Ihnen zu zeigen, was ich meine, erstelle ich einen anderen Controller und füge dem Anbieter erneut eine Konsolenanweisung hinzu, damit Sie sehen können, was passiert.

mod.provider ("myProvider", function () {this. $ get = function () {console.log ("MyProviderFunction. $ get () aufgerufen."); // ADDED this line return "My Value";}; }); mod.controller ("MyController", Funktion (myProvider) {console.log ("MyController - myProvider:" + myProvider);}); mod.controller ("MyController2", Funktion (myProvider) {// ADDED this controller console.log ("MyController2 - myProvider:" + myProvider);}); CONSOLE OUTPUT MyProviderFunction. $ Get () wird aufgerufen. MyController - myProvider: Mein Wert MyController2 - myProvider: Mein Wert

Öffnen Sie in JS Fiddle

Wie Sie sehen, wurde die Funktion $ get () nur einmal aufgerufen.

Beachten Sie, dass wir eine Reihe von Code für den Anbieter geschrieben haben, nur um eine Methode namens $ get () zu erstellen. Warum nicht, anstatt eckig eine Funktion zu geben, die eine andere Funktion definiert, warum nicht einfach die Funktion geben, die wir stattdessen direkt ausführen möchten? Nun, das kann Angular eine Fabrik nennen.

Eine Fabrik

In einer Factory stellen Sie nur den Funktionskörper für die $ get-Methode bereit und Angular erledigt den Rest. Im Folgenden sehen Sie, wie der neue Code aussieht, da Sie sehen werden, dass er sich genauso verhält.

mod.factory ("myProvider", function () {// "provider" in "factory" geändert console.log ("Factory-Funktion aufgerufen."); return "My Value";}); mod.controller ("MyController", Funktion (myProvider) {console.log ("MyController - myProvider:" + myProvider);}); mod.controller ("MyController2", Funktion (myProvider) {console.log ("MyController2 - myProvider:" + myProvider);}); KONSOLENAUSGANG Werksfunktion aufgerufen. MyController - myProvider: Mein Wert MyController2 - myProvider: Mein Wert

Öffnen Sie in JS Fiddle

Jetzt fragen Sie sich vielleicht, warum Sie jemals einen Anbieter verwenden sollten, wenn Sie dasselbe mit einer Fabrik mit weniger Code erreichen können. Es gibt ein paar Gründe, auf die ich später noch eingehen werde. Im Moment möchte ich dem Titel dieses Beitrags treu bleiben und den Unterschied zwischen diesen beiden (Anbieter und Fabrik) und einem Dienst ansprechen.

Bisher haben wir einen einfachen Zeichenfolgenwert zurückgegeben, aber in der Praxis möchten wir wahrscheinlich die meiste Zeit ein Objekt zurückgeben. Nun, das würde unser Beispiel nicht sehr ändern. Wir können die Zeichenfolge, die wir zurückgeben, sehr einfach gegen ein Objekt austauschen.

Lassen Sie uns dies beispielsweise tun, indem Sie ein Objekt zurückgeben, das eine Funktion namens getValue () enthält. Jetzt gibt es verschiedene Möglichkeiten, ein Objekt in JavaScript zu erstellen. Wir verwenden den Ansatz "Objektkonstruktor", bei dem wir eine Funktion erstellen, die ein Objekt mit Eigenschaften und Funktionen auffüllt und das neue Schlüsselwort verwendet, um es zu instanziieren.

Funktion MyObject () {// ADDED unser Objektkonstruktor this.getValue = function () {return "My Value"; }; } mod.factory ("myProvider", function () {console.log ("Factory-Funktion aufgerufen."); neues MyObject () zurückgeben; // Instanz unseres Objekts ERSTELLEN}); mod.controller ("MyController", Funktion (myProvider) {console.log ("MyController - myProvider:" + myProvider.getValue ()); // GEÄNDERT, um getValue ()} aufzurufen); mod.controller ("MyController2", Funktion (myProvider) {console.log ("MyController2 - myProvider:" + myProvider.getValue ()); // GEÄNDERT, um getValue ()} aufzurufen); KONSOLENAUSGANG Werksfunktion aufgerufen. MyController - myProvider: Mein Wert MyController2 - myProvider: Mein Wert

Öffnen Sie in JS Fiddle

Jetzt möchte ich eine kleine Änderung daran vornehmen, da dies gut zum nächsten Konzept führen wird. In unserem Beispiel erstellen wir die Funktion "Object Constructor" MyObject (). Da wir sie jedoch nur an einer Stelle instanziieren, können wir stattdessen eine anonyme Funktion verwenden.

Dies ist eine sehr kleine Änderung. An Stelle von:

Funktion MyObject () {this.getValue = function () {return "My Value"; }; } mod.factory ("myProvider", function () {console.log ("Factory-Funktion aufgerufen."); neues MyObject () zurückgeben;});

Wir machen das:

mod.factory ("myProvider", function () {console.log ("Factory-Funktion aufgerufen."); return new function () {// INLINED unser Objektkonstruktor this.getValue = function () {return "My Value"; };};});

Das Ganze sieht jetzt so aus:

mod.factory ("myProvider", function () {console.log ("Factory-Funktion aufgerufen."); return new function () {// INLINED unser Objektkonstruktor this.getValue = function () {return "My Value"; };};}); mod.controller ("MyController", Funktion (myProvider) {console.log ("MyController - myProvider:" + myProvider.getValue ());}); mod.controller ("MyController2", Funktion (myProvider) {console.log ("MyController2 - myProvider:" + myProvider.getValue ());});

Öffnen Sie in JS Fiddle

Da unsere gesamte Fabrik aus einem einzigen Objekt besteht, wäre es nicht schön, wenn wir Angular einfach die Objektkonstruktorfunktion geben könnten, anstatt diese funky aussehende Fabrik schreiben zu müssen. Sie haben Glück, genau das ist ein Service.

Zu Ihren Diensten

Hier ist derselbe Code, außer dass ein Dienst anstelle einer Fabrik verwendet wird.

mod.service ("myProvider", function () {// "factory" in "service" geändert // HINWEIS: Die einzige übergebene Funktion ist der Objektkonstruktor vor this.getValue = function () {return "My Value" ;};}); mod.controller ("MyController", Funktion (myProvider) {console.log ("MyController - myProvider:" + myProvider.getValue ());}); mod.controller ("MyController2", Funktion (myProvider) {console.log ("MyController2 - myProvider:" + myProvider.getValue ());}); KONSOLE-AUSGABE MyController - myProvider: Mein Wert MyController2 - myProvider: Mein Wert

Öffnen Sie in JS Fiddle

Anbieter vs Fabrik vs Service

Zusammenfassend sind also Anbieter, Fabrik und Service alle Anbieter. Eine Factory ist ein Sonderfall eines Anbieters, wenn Sie in Ihrem Anbieter lediglich eine $ get () - Funktion benötigen. Sie können es mit weniger Code schreiben. Ein Service ist ein Sonderfall einer Factory, wenn Sie eine Instanz eines neuen Objekts zurückgeben möchten, mit dem gleichen Vorteil, weniger Code zu schreiben.

Wann sollte man eins gegen das andere verwenden?

Die Antwort ist, dass Sie die spezialisierteste Version verwenden, die Ihr Ziel erreicht. Angenommen, Sie geben ein vorhandenes Objekt zurück, das an einer anderen Stelle definiert ist und Konstruktorargumente akzeptiert. Sie können keine Argumente an den Dienst übergeben, daher würden Sie den Anruf stattdessen mit einer Factory tätigen.

mod.factory ("myProvider", function () {console.log ("Factory-Funktion aufgerufen."); neue SomeMessageBoxClass ("benutzerdefiniertes Argument") zurückgeben;});

Einer der Hauptfaktoren für die Entscheidung zwischen einem Anbieter und einer Factory ist, ob Sie das generierte Objekt konfigurieren möchten, bevor es generiert wird. Sie tun dies, indem Sie module.config () aufrufen und eine Instanz an den Anbieter selbst senden (anstelle des vom Anbieter zurückgegebenen Objekts). Sie tun dies, indem Sie "Provider" an das Ende des Namens Ihres Providers anhängen, wenn Sie ihn injizieren.

Hier ist ein Beispiel, wie Sie das tun würden:

mod.provider ("myProvider", function () {this.value = "Mein Wert"; this.setValue = function (newValue) {this.value = newValue;}; this. $ get = function () {return this. Wert; }; }); mod.controller ("MyController", Funktion (myProvider) {console.log ("MyController - myProvider:" + myProvider);}); mod.config (function (myProviderProvider) {// ADDED config section // Beachten Sie das zusätzliche Suffix "Provider" myProviderProvider.setValue ("New Value");});

Dies umfasst, wann die drei Anbieter verwendet werden müssen: Anbieter, Fabrik und Service. Es gibt einen zusätzlichen Anbieter, der hier nicht erwähnt wurde, der ein weiterer Sonderfall ist, und das ist der Wertanbieter.

Wenn Sie sich erinnern, als wir den Factory-Anbieter oben zum ersten Mal vorgestellt haben, haben wir das einfache Beispiel für die Rückgabe eines Zeichenfolgenwerts angegeben. Das sah so aus:

mod.factory ("myProvider", function () {return "My Value";});

Nun, wir hätten das tatsächlich mit dem Werteanbieter tun können, was wiederum den Vorteil hat, dass Sie es mit weniger Code tun können. Der folgende Code macht dasselbe wie der obige Code:

mod.value ("myProvider", "My Value");

Wann würden Sie eines gegen das andere verwenden? Vermutlich würden Sie den Factory-Provider verwenden, wenn Sie den Wert basierend auf anderen Daten berechnen möchten, z. B. Daten von einem anderen Werteanbieter oder einer externen Quelle. Und / oder wann Sie den Wert genau dann berechnen möchten, wenn er zum ersten Mal angefordert wird. Hier sind einige Beispiele:

// Beispiel, bei dem die Factory von einem "Wert" -Anbieter abhängt mod.value ("multiple", 3); mod.factory ("Wert", Funktion (mehrfach) {return 10 * multiple;}); // Beispiel, in dem die Factory von externen Daten abhängt mod.factory ("Wert", Funktion (mehrere) {var multiple = getDateFromExternalPage (); return 10 * multiple;});

Habe ich impliziert, dass der Wert der einzige andere Anbieter war? Nun, ich habe gelogen, es gibt eine andere, die dem Wert sehr ähnlich ist, mit zwei kleinen Unterschieden. Dieser Anbieter wird als konstant bezeichnet.

Der Unterschied zwischen Wert und Konstante besteht darin, dass während der Konfigurationsphase ein mit Konstante angegebener Wert verfügbar ist. Sie erinnern sich vielleicht von früher, dass ich erwähnt habe, dass der Anbieter in der Konfigurationsphase zugänglich war, Service und Factory jedoch nicht.

Nun, es ist dasselbe für Wert und Konstante. Konstante ist in der Konfigurationsphase verfügbar und Wert nicht. Der andere Unterschied besteht darin, dass der Wert einer Konstante nicht geändert werden kann, wie der Name schon sagt. Der erste Wert, den Sie ihm zuweisen, ist der Wert, den er behält. Wenn Sie später versuchen, ihm einen anderen Wert zuzuweisen, wird er ignoriert.

Hier ist ein Beispiel:

mod.value ("myValue", "First Assignment"); mod.value ("myValue", "Second Assignment"); mod.constant ("myConstant", "First Assignment"); mod.constant ("myConstant", "Zweite Zuweisung"); mod.controller ("MyController", Funktion (myValue, myConstant) {console.log ("myValue:" + myValue); console.log ("myConstant:" + myConstant);}); KONSOLE AUSGABE myValue: Zweite Zuordnung myConstant: Erste Zuordnung

Hier ist eine Zusammenfassung, wann jeder verwendet werden soll:

Wert

Sie geben einen einfachen Literalwert an.

mod.value ("myValue", 10);
    

Konstante

Sie müssen während der Konfigurationsphase auf diesen Wert zugreifen können. (mit .config ())

mod.constant ("myValue", 10); mod.config (function (myValue) {console.log (myValue);});

Fabrik

Der von Ihnen angegebene Wert muss anhand anderer Daten berechnet werden.

mod.factory ("myFactory", function () {return 10;});
        

Bedienung

Sie geben ein Objekt mit Methoden zurück.

mod.service ("myService", function () {var name = "Bob"; this.setName = function (newName) {this.name = newName;}; this.getName = function () {return this.name;} });
        

Anbieter

Sie möchten in der Konfigurationsphase das Objekt konfigurieren können, das vor seiner Erstellung erstellt werden soll.

mod.provider ("greeter", function () {var name; this.setName = function (newName) {name = newName;}; this. $ get = function () {return new function () {this.sayHi = function () {console.log ("Hi" + name;};};};}); mod.config (function (greeterProvider) {greeterProvider.setName ("John");});
        

Um den Punkt ein letztes Mal nach Hause zu bringen, ist hier ein Bild eines Anbieters mit den hervorgehobenen Werks-, Wert- und Serviceteilen:


Antwort 2:

Intern verwendet AngularJS Factory zum Erstellen eines Serviceobjekts und Provider zum Erstellen eines Factory-Objekts.

Eine Fabrik tut,

  1. Erstellen eines Objekts / einer InstanzKonstruieren / Initialisieren Sie das erstellte Objekt / Instanzeturnieren Sie das erstellte Objekt / die erstellte Instanz

Betrachten Sie Angular Factory als abstraktes Factory-Entwurfsmuster, um den Kontext festzulegen. AngularJS bietet Ihnen die Möglichkeit, ein Objekt Ihrer Wahl mit Ihrer Factory-Methode zu erstellen. Sie geben das erstellte Objekt zurück, damit Ihre Anwendung es als Service verwenden kann.

Im folgenden Beispiel haben Sie die Wahl zwischen zwei Zahlungsgateways, wobei jemand Ihren Code / Ihre Bibliothek verwendet. Ihre Factory-Methode kann entscheiden, ob ein Paypal- oder ein Stripe-Objekt erstellt werden soll. Dies ist Abstract Factory sehr ähnlich. Die Benutzer von paymentService wissen nicht, welcher Service für das Zahlungsgateway verwendet wird.

var myModule = angle.module ('myModule', []); myModule.constant ("PaymentGatewayName", "Stripe"); // oder "Paypal" myModule.factory ('paymentService', Funktion (PaymentGatewayName) {var payService; // Sie entscheiden, welches Objekt basierend auf den geschäftlichen Anforderungen erstellt werden soll // StripeGateway und PaypalGateway sind JavaScript-Klassen PaymentGatewayName == "Stripe") {payService = new StripeGateway (); // Benutzerdefinierter Code zum Initialisieren des Stripe Gateways} else (PaymentGatewayName == "Paypal") {paymentService = new PaypalGateway (); // Benutzerdefinierter Code zum Initialisieren von Paypal} / / Benutzerdefinierter Code zum Initialisieren von paymentService return payService;});

Wenn ein Service-Code so aussieht, bemerken Sie das Schlüsselwort "this". Das bedeutet, dass das Objekt bereits von Angular Core für Sie erstellt wurde und Sie die Objekterstellung nicht mehr steuern.

var myModule = angle.module ('myModule', []); myModule.service ('Cache', function () {var localVariable = ""; // kann außerhalb von this.cacheSize = 5 nicht aufgerufen werden; // 5 MB this.objectsSize = 1000; // max 1000 Objekte this.put = function (Schlüssel, Wert) {...} this.get = function (get) {return ...}});

Antwort 3:

Die große Frage in AngularJS: Service vs Factory v / s Provider. Was soll ich verwenden?

Es gibt unzählige Ressourcen im Internet, die das Thema diskutieren. Es stellt sich heraus, dass diese Frage immer noch jede Woche oder so auf verschiedenen Kanälen auftaucht, und selbst nachdem Sie die zehn besten Antworten auf StackOverflow gelesen haben, ist sie immer noch nicht sehr klar.

Wenn Sie denken, dass sie ähnlich sind, haben Sie Recht. Sie sind sehr ähnlich. In der Tat sind sie alle das gleiche. Sie sind alle Anbieter.

Lesen Sie den vollständigen Artikel -> AngularJS: Service v / s Factory v / s Provider - Bereiten Sie das Interview in 15 Minuten vor