AngularJS stellt in seiner Dokumentation klar fest, dass Services Singletons sind:
AngularJS services are singletons
Gibt intuitiv module.factory
auch eine Singleton-Instanz zurück.
Was ist der beste Weg, um die Factory-Methode zum Zurückgeben von Instanzen eines Dienstes zu implementieren, damit jedes Mal, wenn eine ExampleService
Abhängigkeit deklariert wird, eine andere Instanz von erfüllt wird , da es viele Anwendungsfälle für Nicht-Singleton-Dienste gibt ExampleService
?
Antworten:
Ich denke nicht, dass wir jemals eine Fabrik haben sollten, die eine
new
fähige Funktion zurückgibt, da dies die Abhängigkeitsinjektion zusammenbricht und sich die Bibliothek ungeschickt verhält, insbesondere für Dritte. Kurz gesagt, ich bin mir nicht sicher, ob es legitime Anwendungsfälle für Nicht-Singleton-Dienste gibt.Eine bessere Möglichkeit, dasselbe zu erreichen, besteht darin, die Factory als API zu verwenden, um eine Sammlung von Objekten mit den damit verbundenen Getter- und Setter-Methoden zurückzugeben. Hier ist ein Pseudocode, der zeigt, wie die Verwendung dieser Art von Dienst funktionieren könnte:
Dies ist nur ein Pseudocode, um ein Widget nach ID zu suchen und dann die am Datensatz vorgenommenen Änderungen zu speichern.
Hier ist ein Pseudocode für den Dienst:
Obwohl in diesem Beispiel nicht enthalten, können diese Arten von flexiblen Diensten auch den Status problemlos verwalten.
Ich habe momentan keine Zeit, aber wenn es hilfreich ist, kann ich später einen einfachen Plunker zusammenstellen, um dies zu demonstrieren.
quelle
$resource
.Ich bin mir nicht ganz sicher, welchen Anwendungsfall Sie zu befriedigen versuchen. Es ist jedoch möglich, dass eine Factory Instanzen eines Objekts zurückgibt. Sie sollten dies an Ihre Bedürfnisse anpassen können.
JsFiddle
Aktualisiert
Betrachten Sie die folgende Anforderung für Nicht-Singleton-Dienste . In dem Brian Ford bemerkt:
und sein Beispiel für die Rückgabe von Instanzen aus Fabriken:
Ich würde auch argumentieren, dass sein Beispiel überlegen ist, da Sie das
new
Schlüsselwort nicht in Ihrem Controller verwenden müssen. Es ist in dergetInstance
Methode des Dienstes gekapselt .quelle
ngInfiniteScroll
und einem benutzerdefinierten Suchdienst, damit ich die Initialisierung bis zu einem Klickereignis verzögern kann. JSFiddle der ersten Antwort mit der zweiten Lösung aktualisiert: jsfiddle.net/gavinfoley/G5ku5new
ist die Verwendung deklarativ und es ist einfach, sofort zu erkennen, welche Dienste Singletons sind und welche nicht. Basierend darauf, ob ein Objekt neu erstellt wird.Eine andere Möglichkeit besteht darin, das Serviceobjekt mit zu kopieren
angular.extend()
.und dann zum Beispiel in Ihrem Controller
Hier ist ein Plunk .
quelle
Ich weiß, dass dieser Beitrag bereits beantwortet wurde, aber ich denke immer noch, dass es einige legitime Szenarien gibt, für die Sie einen Nicht-Singleton-Dienst benötigen. Angenommen, es gibt eine wiederverwendbare Geschäftslogik, die von mehreren Controllern gemeinsam genutzt werden kann. In diesem Szenario wäre der beste Ort, um die Logik zu platzieren, ein Dienst, aber was ist, wenn wir einen Zustand in unserer wiederverwendbaren Logik beibehalten müssen? Dann benötigen wir einen Nicht-Singleton-Dienst, der in der App von verschiedenen Controllern gemeinsam genutzt werden kann. So würde ich diese Dienste implementieren:
quelle
Hier ist mein Beispiel für einen Nicht-Singleton-Dienst. Er stammt von einem ORM, an dem ich arbeite. Im Beispiel zeige ich ein Basismodell (ModelFactory), das Dienste ('Benutzer', 'Dokumente') erben und potenziell erweitern sollen.
In meinem ORM fügt ModelFactory andere Dienste ein, um zusätzliche Funktionen (Abfrage, Persistenz, Schemazuordnung) bereitzustellen, die mithilfe des Modulsystems in einer Sandbox gespeichert werden.
Im Beispiel haben sowohl der Benutzer als auch der Dokumentendienst dieselbe Funktionalität, jedoch ihre eigenen unabhängigen Bereiche.
quelle
Angular bietet nur eine Singleton- Service- / Factory-Option. Eine Möglichkeit besteht darin, einen Factory-Service zu haben, der eine neue Instanz für Sie in Ihrem Controller oder anderen Consumer-Instanzen erstellt. Das einzige, was injiziert wird, ist die Klasse, die neue Instanzen erstellt. Dies ist ein guter Ort, um andere Abhängigkeiten einzufügen oder Ihr neues Objekt gemäß der Spezifikation des Benutzers zu initialisieren (Hinzufügen von Diensten oder Konfiguration).
In Ihrer Consumer-Instanz benötigen Sie dann den Factory-Service und rufen die Build-Methode in der Factory auf, um bei Bedarf eine neue Instanz abzurufen
Sie können sehen, dass es die Möglichkeit bietet, bestimmte Dienste zu injizieren, die im Werksschritt nicht verfügbar sind. Auf der Factory-Instanz kann immer eine Injektion erfolgen, die von allen Model-Instanzen verwendet wird.
Hinweis: Ich musste Code entfernen, damit ich möglicherweise Kontextfehler machte. Wenn Sie ein Codebeispiel benötigen, das funktioniert, lassen Sie es mich wissen.
Ich glaube, dass NG2 die Option haben wird, eine neue Instanz Ihres Dienstes an der richtigen Stelle in Ihrem DOM einzufügen, sodass Sie keine eigene Factory-Implementierung erstellen müssen. muss abwarten und sehen :)
quelle
Ich glaube, es gibt gute Gründe, eine neue Instanz eines Objekts innerhalb eines Dienstes zu erstellen. Wir sollten auch offen bleiben, anstatt nur zu sagen, wir sollten so etwas niemals tun, aber der Singleton wurde aus einem bestimmten Grund so hergestellt . Controller werden häufig innerhalb des Lebenszyklus der App erstellt und zerstört, die Dienste müssen jedoch dauerhaft sein.
Ich kann mir einen Anwendungsfall vorstellen, in dem Sie einen Workflow haben, z. B. das Akzeptieren einer Zahlung, und Sie mehrere Eigenschaften festgelegt haben, aber jetzt die Zahlungsart ändern müssen, weil die Kreditkarte des Kunden fehlgeschlagen ist und eine andere Form von bereitgestellt werden muss Zahlung. Dies hat natürlich viel mit der Art und Weise zu tun, wie Sie Ihre App erstellen. Sie können alle Eigenschaften für das Zahlungsobjekt zurücksetzen oder eine neue Instanz eines Objekts innerhalb des Dienstes erstellen . Sie möchten jedoch weder eine neue Instanz des Dienstes noch die Seite aktualisieren.
Ich glaube, eine Lösung besteht darin, ein Objekt innerhalb des Dienstes bereitzustellen, von dem Sie eine neue Instanz erstellen und festlegen können. Um jedoch klar zu sein, ist die einzelne Instanz des Dienstes wichtig, da ein Controller möglicherweise viele Male erstellt und zerstört wird, die Dienste jedoch persistent sein müssen. Was Sie suchen, ist möglicherweise keine direkte Methode in Angular, sondern ein Objektmuster, das Sie in Ihrem Service verwalten können.
Als Beispiel habe ich eine Reset- Taste gemacht. (Dies wird nicht getestet, sondern ist nur eine kurze Vorstellung von einem Anwendungsfall zum Erstellen eines neuen Objekts innerhalb eines Dienstes.
quelle
Hier ist ein weiterer Ansatz für das Problem, mit dem ich sehr zufrieden war, insbesondere in Kombination mit Closure Compiler mit aktivierten erweiterten Optimierungen:
quelle