2014-09-16 8 views
29

Ich brauche Beratung zum Entwerfen einer AngularJS-Anwendung mit mehreren komplexen Modulen und basierend auf der Benutzerrolle das Modul wird nach Authentifizierung & Autorisierung geladen. Einige Benutzer könnten Zugang zu einem einfachen Modul haben und einige könnten ein Dashboard haben und einige könnten Zugang zu 2+ Modulen haben.Große AngularJS Anwendungsdesign

Es gibt viele Richtlinien, die wir identifiziert haben, die über verschiedene Module wiederverwendet werden können. Während der Planungsphase haben wir die folgenden Dinge identifiziert, die existieren sollten, und wir haben Antworten für einige der unten genannten Punkte, aber wir müssen noch Ratschläge von Experten:

  • A Modul
    • Partials
    • haben könnte
    • Controller
    • Richtlinie
    • Dienstleistungen
  • Exceptio n Handhabung (HTTP-Statuscode oder Geschäft Fehler)
  • Logging (mit Zeilennummer, von der Funktion)
  • auch müssen die protokollierten Informationen in dem Server
  • Sollte die Fähigkeit aktivieren müssen sparen und Ausschalten der Protokollierung
  • eigene Widgets über Fabrikklasse (wiederverwendet in anderen Modulen)
  • Geteilt-Richtlinien (isoliert scope)
  • Geteilt Module
  • Geteilt Utilities (Sortieren, filtern, etc.)
  • Enumeratoren gemäß Stammdaten
  • Constants über Singletons
  • Authentication (CSRF)
  • Offline-Speicher
  • REST Dienste
  • Ereignis für die von einem Modul Dispatching Handhabungs- und es in anderen

Handhabungs Die Benutzeroberfläche der Anwendung sieht wie folgt aus: Eine feste Menüleiste oben auf der Seite mit einer Dropdown-Navigation oben links mit mehreren Links, abhängig von der Rolle des Benutzers. Wenn der Benutzer auf einen Link klickt, sollte das entsprechende Modul in die Seite geladen werden. Es muss ein leeres Projekt vorhanden sein, das manuell gestartet wird und die anderen Module zur Laufzeit lädt.

Unser Ansatz ist die folgende Ordnerstruktur haben:

  • App
    • Vermögenswerte
      • css
      • lib js
      • Bilder
    • gemeinsame Komponenten
      • Richtlinien
      • Dienstprogramme
      • Authentifizierung
      • Service-Proxy ruft die $ Ressource zu halten
      • Aufzählungen
      • Konstanten
    • Modell
      • Einheit json (zB Kunde, Produkt, etc.)
    • Geschäft Modul A
      • Partials
      • Richtlinien
      • Dienstleistungen
      • Controller
    • Geschäfts Modul B
    • Business-Modul C
    • index.html
    • Requirejs Konfigurationsdatei

Also meine Fragen sind:

  • Wie kann ein Dienst innerhalb eines Moduls zu anderen Modul reden?
  • Modul sollte entwickelt und unabhängig ausgeführt werden?
  • Wie kann die Kommunikation zwischen Modulen mit Daten übertragen werden?
  • Wie integriert man alle oben genannten Elemente, insbesondere die Ausnahmebehandlung, Protokollierung?
  • Entwickler sollten die Konvention verstehen, die wir definiert haben?
  • Welche Methode für die Protokollierung, Senden von Informationen zwischen Modul aufrufen?
+1

Ich denke, das vollständige Beispiel ist hier http://ify.io/using-requirejs-with-optimization-for-lazy-loading-angularjs-artefacts/ – Shohel

+0

Dank Shohel, wir haben die Lazy-loading behandelt. Meine Zweifel bestehen eher darin, wie man eine skalierbare Anwendung entwerfen kann, mit mehr als 20 Entwicklern kann die minimale Abhängigkeit funktionieren. Und wie man all das Feature mit einigen definierten Konventionen zusammenbringt. Versuch zu zeichnen und Architekturdiagramm. – Anandh

+0

Kein Problem. Sie arbeiten nur mit ihrer seitenweisen Javascript-Datei, wie Controller, Service und Direktive, Sie müssen einen gemeinsamen Service, Factory erstellen. – Shohel

Antwort

8

Viele gute Fragen zu stellen sind; Sie scheinen in zwei Hauptgruppen zu sein - die erste ist eine Frage der Code-Struktur und die zweite ist über Metriken (Protokolle usw.).

Wie kann ein Dienst innerhalb eines Moduls mit einem anderen Modul kommunizieren?

Sie sollten idealerweise Richtlinien für Ihre Module verwenden. Auf diese Weise können Sie Controller über die Eigenschaft require verknüpfen. Here is a page on sharing data between directives and controllers.

Modul sollte entwickelt und unabhängig ausgeführt werden?

Ich nehme an, Sie denken über Komponententests nach. Ja, Ihre Module sollten idealerweise so eng wie möglich sein, um das Testen zu erleichtern.

Wie kann die Kommunikation zwischen den Modulen mit der Datenübertragung gehandhabt werden?

Hier wird typischerweise services verwendet. Hinweis: Dienste, Fabriken und Anbieter bedeuten in AngularJS alle das Gleiche, sie werden nur leicht unterschiedlich deklariert. Wählen Sie den, mit dem Sie sich am wohlsten fühlen.

Wie integriert man alle oben genannten Elemente, insbesondere die Ausnahmebehandlung, Protokollierung?

Protokollierung ist ein separates Problem. Das Schöne an AngularJS ist, dass Sie sehr einfach vorhandene Teile des Frameworks erweitern können, um Funktionen oder Verhaltensweisen hinzuzufügen, wie Sie es für richtig halten. Sie tun dies mit decorators. Here is an example of exception logging that I think will cover any use cases you might be interested in

Entwickler sollten die Konvention verstehen, die wir definiert haben?

Die Antwort darauf ist immer die gleiche: Kommunikation ist, wie sie wissen. Entwickler müssen die Konvention sozialisieren, sonst wirst du nie Buy-in bekommen.

Welche Methode zum Protokollieren, Senden von Informationen zwischen Modul aufrufen?

Beantwortet oben.

16

Ich empfehle yeoman in den Workflow einzubinden und einen Generator für Ihr Projekt verwenden, das viel einfacher, den Weg macht, die Sie Ihre Anwendung strukturieren, besonders, wenn Sie in einem Team arbeiten.Zu Beginn dieses Jahres haben Leute von angular eine document mit Best Practices für Ihre App-Struktur veröffentlicht, ich empfehle Ihnen, sie zu lesen, da es einen Generator gibt, der auf diesen Best Practices namens cg-angular basiert, was ich uneingeschränkt empfehlen kann.

Ich werde zitiert aus cg-Winkel Website:

Alle Teilgeneratoren fordern den Benutzer angeben, wo die neuen Dateien zu speichern. So können Sie beliebige Verzeichnisstrukturen erstellen, einschließlich einschließlich Verschachtelung. Der Generator erstellt eine Handvoll Dateien im Stammverzeichnis Ihres Projekts, einschließlich index.html, app.js und app.less. Sie bestimmen, wie der Rest des Projekts strukturiert sein wird.

in Bezug auf Ihre Fragen:

  • Wie kann ein Dienst innerhalb eines Moduls zu anderen Modul reden?

Sie einen Ordner für Richtlinien erstellen können/und Dienstleistungen/Sie gehen in verschiedenen Modulen wiederzuverwenden.

  • Modul sollte entwickelt und unabhängig ausgeführt werden?

Sie mehrere Module innerhalb einer App haben kann (man sie als laden könnte benötigt werden, vielleicht benötigen mit js aber das ist offtopic)

  • Wie die Kommunikation zwischen Modul gehandhabt werden kann mit der Übertragung von Daten?

Verwenden Dienstleistungen Informationen zwischen den Controllern passieren, in verschiedenen Module

  • Wie alle oben genannten Elemente zu integrieren, insbesondere Ausnahmebehandlung, Protokollierung?

Sie können einen allgemeinen Fehler-Handler tun und ein generisches http-Interceptor für alle Module

  • Entwickler die Konvention verstehen sollte wir definiert haben?

Verwendung ein Generator sie opinioated sind und sie geben den Auftrag und die Konventionen Sie für ein Team benötigen.

7

-Code-Organisation in Groß AngularJS und JavaScript-Anwendungen

Viele Entwickler kämpfen mit, wie eine Anwendung Code Basis zu organisieren, sobald es in der Größe wächst. Ich habe dies kürzlich in AngularJS und JavaScript-Anwendungen gesehen, aber in der Vergangenheit war es ein Problem über alle Technologien einschließlich vieler Java-und Flex-Apps, die ich in der Vergangenheit gearbeitet habe.

Der allgemeine Trend ist eine Besessenheit, Dinge nach Typ zu organisieren. Es trägt eine frappierende Ähnlichkeit mit der Art und Weise, wie Menschen ihre Kleidung organisieren .

Piles auf dem Boden

Lassen Sie uns in Winkel-Samen einen Blick darauf werfen, den offiziellen Startpunkt für AngularJS Apps. Die "App" enthält die folgende Struktur:

css/img/js/app.js controllers.js directives.js filters.js services.js lib/partials/Die JavaScript-Verzeichnis hat eine Datei für jede Art von Objekt schreiben wir. Dies ist ähnlich wie Ihre Kleidung in verschiedene Stapel auf dem Boden zu organisieren. Sie haben einen Haufen Socken, Unterwäsche, Hemden, Hosen, etc. Sie wissen, dass Ihre schwarzen Wollsocken sind in Stapel in der Ecke, aber es wird eine Weile dauern, um sie zu graben heraus.

Dies ist ein Durcheinander. Leute sollten nicht so leben und Entwickler sollten nicht so kodieren. Sobald Sie über ein halbes Dutzend oder so Controller oder Dienstleistungen diese Dateien werden unhandlich sind: Objekte Sie suchen sind schwer zu finden, werden Datei Changesets in der Quellcodeverwaltung opak, usw.

Die Sockenschublade

Der nächste logische Durchlauf beim Organisieren von JavaScript umfasst das Erstellen eines Verzeichnisses für einige der Archetypen und das Aufteilen von Objekten in ihre eigenen Dateien . Um die Metapher der Kleidung fortzusetzen, haben wir jetzt in eine nette Mohaghony-Kommode investiert und planen, Socken in eine Schublade zu stecken, Unterwäsche in eine andere, und ordentlich unsere Hosen und Hemden in noch andere falten.

Stellen wir uns vor, wir bauen eine einfache E-Commerce-Website mit einem Login Flow, Produktkatalog und Einkaufswagen UIs. Wir haben außerdem neue Archetypen für Modelle (Geschäftslogik und -status) und Dienste (Proxies für HTTP/JSON-Endpunkte) definiert, anstatt sie in Angulars einzigem "Service" -Datentyp zu integrieren. Unser JavaScript Verzeichnis kann nun wie folgt aussehen:

Controller/LoginController.js RegistrationController.js ProductDetailController.js SearchResultsController.js directives.js filters.js models/CartModel.js ProductModel.js SearchResultsModel.js UserModel.js Dienstleistungen/CartService.js UserService.js ProductService.js Nizza! Objekte können jetzt einfach durch Durchsuchen der Dateistruktur oder mit IDE-Verknüpfungen, Änderungssets in der Versionskontrolle jetzt deutlich angezeigt werden, was wurde geändert, etc.Dies ist eine große Verbesserung, leidet aber immer noch unter einigen Einschränkungen.

Stellen Sie sich vor, Sie sind im Büro und erkennen, dass Sie ein paar Outfits brauchen für eine Geschäftsreise morgen früh gereinigt. Sie rufen zu Hause an und fragen Sie Ihren Lebensgefährten, Ihre schwarzen Holzkohle und blauen Nadelstreifenanzüge zu den Reinigern zu nehmen. Und vergessen Sie nicht das graue Hemd mit die schwarze Paisley-Krawatte und das weiße Hemd mit der festen gelben Krawatte. Stellen Sie sich vor, dass Ihr Lebensgefährte mit der Ihrer Kommode und Garderobe völlig unvertraut ist. Während sie sich durch Ihre Krawattenschublade bewegen, sehen sie drei gelbe Krawatten. Welchen zu wählen?

Wäre es nicht schön, wenn Ihre Kleidung nach Outfit organisiert wäre? Während gibt es praktische Einschränkungen wie Kosten und Platz, die diese mit Kleidung in der realen Welt schwierig machen, kann etwas ähnliches mitCode ohne Kosten getan werden.

Modularer Aufbau

Hoffentlich wird die banalen Metaphern nicht zu langweilig gewesen, aber hier sind die rekapituliert:

Ihre bedeutend andere ist der neue Entwickler im Team, die gefragt gewesen ein Fehler auf einen beheben die vielen Bildschirme in deiner App Der Entwickler durchsucht die Verzeichnisstruktur und sieht alle Controller, Modelle und Services übersichtlich geordnet vor. Leider teilt es ihm nichts darüber mit, welche Objekte verwandt sind oder Abhängigkeiten voneinander haben. Wenn der Entwickler an einem Punkt einen Teil des Codes wiederverwenden möchte, müssen sie Dateien aus einer Reihe von verschiedenen Ordnern sammeln und wird Code aus einem anderen Ordner immer woanders vergessen. Ob Sie es glauben oder nicht, Sie müssen selten alle der Controller aus der E-Commerce-App in der neuen Reporting-App , die Sie erstellen, wiederverwenden. Möglicherweise müssen Sie jedoch einige der Authentifizierungslogik erneut verwenden. Wäre es nicht schön, wenn das alles in einem Platz wäre? Lassen Sie uns die App reorganisieren basierend auf Funktionsbereiche:

Warenkorb/CartModel.js CartService.js common/directives.js filters.js Produkt/Suche/SearchResultsController.js SearchResultsModel.js ProductDetailController.js ProductModel.js ProductService.js user/ LoginController.js RegistrationController.js UserModel.js UserService.js Jeder beliebige Entwickler kann nun den obersten Ordner öffnen und sofort Einblick in die Anwendung erhalten. Objekte im selben Ordner haben eine Beziehung und einige haben Abhängigkeiten auf anderen. Zu verstehen, wie der Anmelde- und Registrierungsprozess funktioniert ist so einfach wie das Durchsuchen der Dateien in diesem Ordner. Primitive Wiederverwendung über Copy/Paste kann mindestens durch Kopieren des Ordners in ein anderes Projekt erreicht werden.

Mit AngularJS können wir dies einen Schritt weiter und ein Modul von diesen zugehörigen Code erstellen:

1 2 3 4 5 6 7 8 9 10 11 12 13 var userModule = angular.module ('userModule ', []); userModule.factory ('userService', ['$ http', Funktion ($ http) {return new UserService ($ http);}]);
userModule.factory ('userModel', ['userService', function (userService) {neues UserModel (userService);}]);
userModule.controller ('loginController', ['$ scope', 'userModel', LoginController]); userModule.controller ('registrationController', ['$ scope', 'userModel', RegistrationController]); view rawUserModule.js gehostet mit ❤ von GitHub Wenn wir dann UserModule.js in den Benutzerordner platzieren, wird es zu einem "Manifest" der Objekte, die in diesem Modul verwendet werden. Dies wäre auch ein sinnvoller Platz um einige Loader-Direktiven für RequireJS oder Browserify hinzuzufügen.

Tipps für Common Code

Jede Anwendung haben gemeinsamen Code, der von vielen Modulen verwendet wird. Wir brauchen nur einen Platz dafür, der ein Ordner namens "common" oder "shared" oder was auch immer Sie mögen. In wirklich großen Anwendungen tendiert man dazu, eine Überlappung von Funktionalität und übergreifenden Bedenken zu haben. Dies kann durch einige Techniken überschaubar gemacht werden:

Wenn die Objekte Ihres Moduls direkten Zugriff auf mehrere "gemeinsame" Objekte benötigen, schreiben Sie eine oder mehrere Fassaden für sie. Dies kann dazu beitragen, die Anzahl der Kollaborateure für jedes Objekt zu reduzieren, da es zu viele Kollaborateure gibt. Wenn Ihr "gemeinsames" Modul groß wird, unterteilen Sie es in Submodule, die einen bestimmten Funktionsbereich oder ein Problem betreffen. Stellen Sie sicher, dass Ihre Anwendungsmodule nur die "gemeinsamen" Module verwenden, die sie benötigen. Dies ist eine Variante des "Interface Trennprinzips" von SOLID. Fügen Sie Hilfsmethoden zu $ ​​rootScope hinzu, damit sie von untergeordneten Bereichen verwendet werden können. Dies kann dazu beitragen, zu verhindern, dass die gleiche Abhängigkeit (z. B. "PermissionsModel") in jeden Controller in der Anwendung verdrahten muss. Beachten Sie, dass dies sparsam durchgeführt werden sollte , um zu vermeiden, den globalen Geltungsbereich zu überlasten und Abhängigkeiten nicht offensichtlich zu machen. Verwenden Sie Ereignisse, um zwei Komponenten zu entkoppeln, die keinen expliziten Verweis auf einander benötigen. AngularJS ermöglicht dies über die Methoden $ emit, $ broadcast und $ on für das Scope-Objekt. Ein Controller kann ein Ereignis auslösen, um eine Aktion auszuführen, und dann eine Benachrichtigung erhalten, dass die Aktion abgeschlossen wurde. Schnelle Anmerkung über Anlagen und Tests

Ich denke, es gibt mehr Spielraum für die Organisation von HTML, CSS und Bilder. Platzieren sie in einem "Assets" Unterordner des Moduls wahrscheinlich die beste Balance zwischen Kapselung der Asset-Abhängigkeiten des Moduls und nicht zu viel Dinge überladen. Allerdings denke ich, ein separater Top-Level-Ordner für diesen Inhalt, der enthält eine Ordnerstruktur, die die Paketstruktur der App spiegelt auch vernünftig ist. Ich denke, es funktioniert auch gut für Tests.

haben Sie einen Blick auf den folgenden Link,

https://blog.safaribooksonline.com/2014/03/27/13-step-guide-angularjs-modularization/