Dies hat mir geholfen, den Unterschied zu verstehen, dank eines Blogposts von Pascal Precht.
Ein Dienst ist eine Methode in einem Modul, die einen Namen und eine Funktion verwendet, die den Dienst definiert. Sie können diesen bestimmten Dienst in andere Komponenten wie Steuerungen, Anweisungen und Filter einfügen und verwenden. Eine Factory ist eine Methode für ein Modul und es werden auch ein Name und eine Funktion verwendet, die die Factory definieren. Wir können es genauso injizieren und verwenden, wie wir es mit dem Service getan haben.
Mit new erstellte Objekte verwenden den Wert der Prototyp-Eigenschaft ihrer Konstruktorfunktion als Prototyp. Daher habe ich den Angular-Code gefunden, der Object.create () aufruft, von dem ich glaube, dass er die Servicekonstruktorfunktion ist, wenn er instanziiert wird. Eine Factory-Funktion ist jedoch nur eine Funktion, die aufgerufen wird. Deshalb müssen wir ein Objektliteral für die Factory zurückgeben.
Hier ist der Winkel-1.5-Code, den ich für die Fabrik gefunden habe:
var needsRecurse = false;
var destination = copyType(source);
if (destination === undefined) {
destination = isArray(source) ? [] : Object.create(getPrototypeOf(source));
needsRecurse = true;
}
Winkelquellcode-Snippet für die Funktion factory ():
function factory(name, factoryFn, enforce) {
return provider(name, {
$get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
});
}
Es nimmt den Namen und die Factory-Funktion, die übergeben wird, und gibt einen Anbieter mit demselben Namen zurück, der eine $ get-Methode hat, die unsere Factory-Funktion ist. Wenn Sie den Injektor nach einer bestimmten Abhängigkeit fragen, fragt er den entsprechenden Anbieter grundsätzlich nach einer Instanz dieses Dienstes, indem er die Methode $ get () aufruft. Aus diesem Grund ist beim Erstellen von Anbietern $ get () erforderlich.
Hier ist der Winkel 1.5 Code für den Service.
function service(name, constructor) {
return factory(name, ['$injector', function($injector) {
return $injector.instantiate(constructor);
}]);
}
Es stellt sich heraus, dass wenn wir service () aufrufen, tatsächlich factory () aufgerufen wird! Es wird jedoch nicht nur unsere Servicekonstruktorfunktion unverändert an das Werk übergeben. Es wird auch eine Funktion übergeben, die den Injektor auffordert, ein Objekt durch den angegebenen Konstruktor zu instanziieren.
Mit anderen Worten, wenn wir MyService irgendwo einfügen, geschieht Folgendes im Code:
MyServiceProvider.$get(); // return the instance of the service
Um es noch einmal zu wiederholen, ruft ein Dienst eine Factory auf, bei der es sich um eine $ get () -Methode des entsprechenden Anbieters handelt. Darüber hinaus ist $ injizor.instantiate () die Methode, die letztendlich Object.create () mit der Konstruktorfunktion aufruft. Deshalb verwenden wir "dies" in Diensten.
Für ES5 spielt es keine Rolle, welche wir verwenden: service () oder factory (), es ist immer eine Factory, die aufgerufen wird und einen Anbieter für unseren Service erstellt.
Genau das Gleiche können Sie aber auch mit Services tun. Ein Service ist jedoch eine Konstruktorfunktion, die uns nicht daran hindert, Objektliterale zurückzugeben. So können wir unseren Servicecode so schreiben, dass er im Grunde genau das Gleiche wie unsere Fabrik tut, oder mit anderen Worten, Sie können einen Service als Fabrik schreiben, um ein Objekt zurückzugeben.
Warum empfehlen die meisten Menschen, Fabriken anstelle von Dienstleistungen zu nutzen? Dies ist die beste Antwort, die ich gesehen habe und die aus Pawel Kozlowskis Buch stammt: Beherrschen der Entwicklung von Webanwendungen mit AngularJS.
Die Factory-Methode ist die häufigste Methode, um Objekte in das AngularJS-Abhängigkeitsinjektionssystem zu übertragen. Es ist sehr flexibel und kann eine ausgefeilte Erstellungslogik enthalten. Da Fabriken reguläre Funktionen sind, können wir auch einen neuen lexikalischen Bereich nutzen, um "private" Variablen zu simulieren. Dies ist sehr nützlich, da wir Implementierungsdetails eines bestimmten Dienstes verbergen können. "