AngularJS‑Tricks
AngularJS kann Spaß machen!
AngularJS KANN Spaß machen!
Für: AngularJS v1.x
- AngularJS‑Entwickler stellen schnell fest, dass ihre mittel‑großen Anwendungen unter dem Gewicht verstreuter
$watchsund der oft aufgeblähten Krücke$scope` zusammenbrechen. - Halten Sie
$scopefrei von überflüssigem UI‑Zustand, versuchen Sie, Größe und Tiefe Ihrer gesamten Hierarchie zu begrenzen.
2‑Way‑Datenbindung: 2‑Way‑Schwert
2‑Way‑Binding allein lässt den Umstieg von anderen Frameworks wie Backbone wirklich beeindruckend wirken.
Das Problem ist: Viele Seiten übernutzen chronisch Angulars Design‑Muster.
Das führt zu einer Ausbreitung von Directives und einem $scope/rootScope, das leicht tausende Instanzen enthält und an riesigen Objekten hängen bleibt, was jede Aussicht auf effektive Garbage‑Collection zunichtemacht.
Sie wissen, worauf das hinausläuft: ein ausgelaugter Browser! Für immer dazu verdammt, mit rasender Geschwindigkeit endlose und redundante UI/DOM‑Re‑Compilings auszuführen.
Stoppen Sie die ÜBER‑Angular.JS‑ifizierung
„Wenn Ihr einziges Werkzeug ein Hammer ist, sieht jedes Problem wie ein Nagel aus.“
– altes Sprichwort
Hat Ihre Anwendung Probleme mit Directives?
current-user-status-label div(ng-if='loggedIn') view-user-surplusage(ng-if='!editMode') .head: contact-details(user='user') .tool: contact-buttons(loggedIn='loggedIn') a.edit-icon(ng-click='editMode = true') edit-user-surplusage(ng-if='editMode') .head: avatar-edit(user='user') .body: edit-contact-details(user='user') a.save-icon(ng-click='editMode = false')Entwerfen wir ein flexibles User‑Widget, das Folgendes ermöglicht:
- Vielseitige Komponentenbildung mit DRY‑Angular‑Code
- Verständliche Directives, mit minimaler Größe/Tiefe (achten Sie auf Ihre ng‑repeats)
- Einfache Service‑Schicht
- Wenig eigentlicher Code – hauptsächlich HTML/View‑Code
// jadeuser-widget div(ng-if='loggedIn') div.edit(ng-if='editMode') h4.email-icon: input(type='email', ng-model='user.email') h4.phone-icon: input(type='email', ng-model='user.phone') a.save-icon(ng-click='editMode = false') div.show(ng-if='!editMode') h1.users-icon {{ user.name }} h4.email-icon {{ user.email }} h4.phone-icon {{ user.phone }} a.edit-icon(ng-click='editMode = true') div(ng-if='!loggedIn') h5: i Welcome User a.btn(href='/login') LoginLösungen
Angular‑Tipps
- Verwenden Sie 1‑Richtungs‑Binding (z. B.
{ :: title }) - Begrenzen Sie rekursive Verschachtelungen von Directives
- Und wenn Sie Directives verschachteln müssen, NIEMALS innerhalb eines
ng-repeat– die Performance kann dann schnell in die Größenordnung vonO(n^2)^3geraten ;) I. Nutzen Sie nativen JS/DOM‑Code in einem Factory‑Pattern, um grundlegende DOM/UI‑Fragmente zu erzeugen, z. B. Modal‑Nachrichtenbox, Statusleiste. Rufen Sie UI‑Factories aus Directives oder Controllers auf. - Bonus: Verstehen Sie Kosten und Auslöser des Browser‑Render‑Lifecycle: Animation, Composite‑Rendering, Reflows
Browserify zum Projekt‑Organisieren einsetzen
Nicht speziell für Angular, aber unverzichtbar für eine einfache Auflösung von Abhängigkeiten.
Browserify macht JS‑Projekte handhabbar, ohne nennenswerten Code‑Overhead (ok, ein paar hundert Zeichen).
Justread this section des Browserify Handbook.
Alternativen
ReactJS von Facebook
Wenn Sie viele kleine wiederverwendbare UI‑Komponenten besitzen – ReactJS könnte die bessere Wahl sein:
- Wenn Ihr Projekt…?:
- Eine andere Philosophie zur UI/DOM‑Implementierung als Angular verfolgt
- Bereits irgendeine Art von „Framework“ nutzt – Sie können ReactJS neben AngularJS, Ember, Backbone einsetzen. (Nach Möglichkeit vermeiden.)
- Häufige Änderungen am Datenmodell im eigenen Code verarbeitet, profitieren Sie davon, das ADHS‑artige Digest/Loop‑Muster von Angular zu umgehen
Polymer Project von Google
###Pure-er JS Ansatz
- Übrigens, hier versuche ich, framework‑agnostischen Code zu schreiben (+1 Testbarkeit, +1 Wiederverwendbarkeit)
- Verwende eine plain‑JavaScript‑Klasse, um Daten zu laden (AJAX/JSONP/Im Seiteninhalt eingebettet usw.)
- Nutze Mustache‑Templating, um HTML‑Strings zu erzeugen (oder direkt DOM)
- Cache den gerenderten Inhalt in
localStorage, sofern möglich - (Optional) Jetzt einen Event‑Listener hinzufügen, um den Inhalt neu zu rendern. Ich habe mich auf den Event‑Namen
refresh.<class-name>standardisiert