Ich arbeite mit AngularJS für mein aktuelles Projekt. In der Dokumentation und in den Tutorials werden alle Modelldaten in den Controller-Bereich gestellt. Ich verstehe, dass es da sein muss, um für den Controller und damit in den entsprechenden Ansichten verfügbar zu sein.
Ich denke jedoch nicht, dass das Modell dort tatsächlich implementiert werden sollte. Es kann komplex sein und beispielsweise private Attribute haben. Außerdem möchte man es möglicherweise in einem anderen Kontext / einer anderen App wiederverwenden. Wenn Sie alles in den Controller einfügen, wird das MVC-Muster vollständig zerstört.
Gleiches gilt für das Verhalten eines Modells. Wenn ich eine DCI-Architektur verwenden und das Verhalten vom Datenmodell trennen würde, müsste ich zusätzliche Objekte einführen, um das Verhalten zu halten. Dies würde durch die Einführung von Rollen und Kontexten geschehen.
DCI == D ata C ollaboration I nteraction
Natürlich könnten Modelldaten und -verhalten mit einfachen Javascript-Objekten oder einem beliebigen "Klassen" -Muster implementiert werden. Aber wie würde AngularJS das machen? Dienste nutzen?
Es kommt also auf diese Frage an:
Wie implementieren Sie vom Controller entkoppelte Modelle gemäß den Best Practices von AngularJS?
quelle
Antworten:
Sie sollten Dienste verwenden, wenn Sie etwas möchten, das von mehreren Controllern verwendet werden kann. Hier ist ein einfaches Beispiel:
quelle
Ich versuche derzeit dieses Muster, das, obwohl nicht DCI, eine klassische Dienst- / Modellentkopplung bietet (mit Diensten für die Kommunikation mit Webdiensten (auch bekannt als Modell CRUD) und einem Modell, das die Objekteigenschaften und -methoden definiert).
Beachten Sie, dass ich dieses Muster nur verwende, wenn das Modellobjekt Methoden benötigt, die an seinen eigenen Eigenschaften arbeiten, die ich wahrscheinlich überall verwenden werde (z. B. verbesserte Getter / Setter). Ich bin nicht systematisch tun dies für jeden Dienst befürworten.
EDIT: Früher dachte ich, dieses Muster würde gegen das Mantra "Winkelmodell ist einfaches altes Javascript-Objekt" verstoßen, aber jetzt scheint es mir, dass dieses Muster vollkommen in Ordnung ist.
EDIT (2): Um noch klarer zu sein, verwende ich eine Model-Klasse nur, um einfache Getter / Setter zu berücksichtigen (z. B. zur Verwendung in Ansichtsvorlagen). Für die Logik großer Unternehmen empfehle ich die Verwendung separater Dienste, die das Modell "kennen", aber von diesen getrennt bleiben und nur Geschäftslogik enthalten. Nennen Sie es eine "Business Expert" -Service-Schicht, wenn Sie möchten
service / ElementServices.js (beachten Sie, wie Element in die Deklaration eingefügt wird)
model / Element.js (mit anglejs Factory, erstellt für die Objekterstellung)
quelle
In der Angularjs-Dokumentation heißt es eindeutig:
Es liegt also an Ihnen, wie Sie ein Modell deklarieren. Es ist ein einfaches Javascript-Objekt.
Ich persönlich werde Angular Services nicht verwenden, da sie sich wie Singleton-Objekte verhalten sollen, mit denen Sie beispielsweise globale Zustände in Ihrer Anwendung beibehalten können.
quelle
DCI ist ein Paradigma und als solches gibt es keine eckige Methode, entweder die Sprachunterstützung DCI oder nicht. JS unterstützt DCI ziemlich gut, wenn Sie bereit sind, die Quellentransformation zu verwenden, und mit einigen Nachteilen, wenn Sie dies nicht tun. Wiederum hat DCI nicht mehr mit Abhängigkeitsinjektion zu tun, als zu sagen, dass eine C # -Klasse dies getan hat und definitiv auch kein Dienst ist. Der beste Weg, DCI mit AngulusJS zu machen, ist also, DCI auf JS-Weise zu machen, was ziemlich nahe daran liegt, wie DCI überhaupt formuliert wird. Wenn Sie keine Quellentransformation durchführen, können Sie dies nicht vollständig tun, da die Rollenmethoden auch außerhalb des Kontexts Teil des Objekts sind. Dies ist jedoch im Allgemeinen das Problem bei DCI mit Methodeninjektion. Wenn Sie sich fullOO.info ansehenAuf der maßgeblichen Website für DCI können Sie sich die Ruby-Implementierungen ansehen, bei denen auch die Methodeninjektion verwendet wird, oder Sie können sich hier weitere Informationen zu DCI ansehen . Es ist meistens mit RUby-Beispielen, aber das DCI-Zeug ist dafür agnostisch. Einer der Schlüssel zu DCI ist, dass das, was das System tut, von dem, was das System ist, getrennt ist. Das Datenobjekt ist also ziemlich dumm, aber sobald es an eine Rolle in einem Kontext gebunden ist, stellen Rollenmethoden ein bestimmtes Verhalten zur Verfügung. Eine Rolle ist einfach ein Bezeichner, nichts weiter. Wenn Sie über diesen Bezeichner auf ein Objekt zugreifen, stehen Rollenmethoden zur Verfügung. Es gibt kein Rollenobjekt / keine Rollenklasse. Bei der Methodeninjektion ist der Umfang der Rollenmethoden nicht genau wie beschrieben, sondern eng. Ein Beispiel für einen Kontext in JS könnte sein
quelle
Dieser Artikel über Modelle in AngularJS könnte helfen:
http://joelhooks.com/blog/2013/04/24/modeling-data-and-state-in-your-angularjs-application/
quelle
Wie auf anderen Postern angegeben, bietet Angular keine sofort einsatzbereite Basisklasse für die Modellierung, es können jedoch mehrere Funktionen bereitgestellt werden:
Eine Bibliothek, die all diese Dinge gut macht, ist ngActiveResource ( https://github.com/FacultyCreative/ngActiveResource) ). Vollständige Offenlegung - ich habe diese Bibliothek geschrieben - und ich habe sie erfolgreich beim Erstellen mehrerer Anwendungen im Unternehmensmaßstab verwendet. Es ist gut getestet und bietet eine API, die Rails-Entwicklern vertraut sein sollte.
Mein Team und ich entwickeln diese Bibliothek weiterhin aktiv weiter, und ich würde gerne sehen, dass mehr Angular-Entwickler dazu beitragen und sie im Kampf testen.
quelle
ngActiveResource
und Angulars$resource
Service sind. Ich bin ein wenig neu in Angular und habe beide Dokumentensätze schnell durchsucht, aber sie scheinen viel Überlappung zu bieten. WurdengActiveResource
entwickelt, bevor der$resource
Service verfügbar war?Eine ältere Frage, aber ich denke, das Thema ist angesichts der neuen Ausrichtung von Angular 2.0 relevanter als je zuvor. Ich würde sagen, eine bewährte Methode besteht darin, Code mit möglichst wenigen Abhängigkeiten von einem bestimmten Framework zu schreiben. Verwenden Sie die Framework-spezifischen Teile nur dort, wo sie einen direkten Mehrwert bieten.
Derzeit scheint der Angular-Dienst eines der wenigen Konzepte zu sein, die es in die nächste Generation von Angular schaffen. Daher ist es wahrscheinlich klug, die allgemeine Richtlinie zum Verschieben der gesamten Logik auf Dienste zu befolgen. Ich würde jedoch argumentieren, dass Sie entkoppelte Modelle auch ohne direkte Abhängigkeit von Angular-Diensten erstellen können. Das Erstellen eigenständiger Objekte mit nur den erforderlichen Abhängigkeiten und Verantwortlichkeiten ist wahrscheinlich der richtige Weg. Es macht das Leben auch viel einfacher, wenn automatisierte Tests durchgeführt werden. Einzelverantwortung ist heutzutage eine Modeerscheinung, aber es macht sehr viel Sinn!
Hier ist ein Beispiel für ein Muster, das ich für gut halte, um das Objektmodell vom Dom zu entkoppeln.
http://www.syntaxsuccess.com/viewarticle/548ebac8ecdac75c8a09d58e
Ein wichtiges Ziel ist es, Ihren Code so zu strukturieren, dass er aus Unit-Tests genauso einfach zu verwenden ist wie aus einer Ansicht. Wenn Sie dies erreichen, sind Sie gut positioniert, um realistische und nützliche Tests zu schreiben.
quelle
Ich habe versucht, genau dieses Problem in diesem Blog-Beitrag anzugehen .
Grundsätzlich ist das beste Zuhause für die Datenmodellierung in Diensten und Fabriken. Abhängig davon, wie Sie Ihre Daten abrufen und wie komplex die von Ihnen benötigten Verhaltensweisen sind, gibt es viele verschiedene Möglichkeiten, die Implementierung durchzuführen. Angular hat derzeit keine Standardmethode oder Best Practice.
Der Beitrag behandelt drei Ansätze: $ http , $ resource und Restangular .
Hier ist ein Beispielcode für jeden mit einem benutzerdefinierten Code
getResult()
Methode für das Jobmodell:Restangular (leicht peasy):
$ resource (etwas komplizierter):
$ http (Hardcore):
Der Blog-Beitrag selbst geht detaillierter auf die Gründe ein, warum Sie die einzelnen Ansätze verwenden könnten, sowie auf Codebeispiele für die Verwendung der Modelle in Ihren Controllern:
AngularJS-Datenmodelle: $ http VS $ resource VS Restangular
Es besteht die Möglichkeit, dass Angular 2.0 eine robustere Lösung für die Datenmodellierung bietet, mit der alle auf dieselbe Seite gelangen.
quelle