senäh

17senäh und so…

mean_thumb

HTML/CSS/JS
01. Nov 2013
Kommentare: 1

AngularJS

Kategorien: HTML/CSS/JS | 01. Nov 2013 | Kommentare: 1

Serie: Einführung in den MEAN Stack

Im heutigen Artikel betreten wir endlich die Clientseite des MEAN Stacks. Während die Datenbank und der Server unerlässlich sind, so ist dennoch der Client der einzige Bereich den der Besucher eine Seite real sieht und mit dem er interagiert. Gerade in den letzten Jahren hat sich dieser Bereich technologisch stark weiterentwickelt. AngularJS zählt dabei zu den fortschrittlichsten und beliebtesten clientseitigen Applikationsframeworks.

AngularJS wird von Google entwickelt und baut auf der MVC-Architektur auf. An dieser Stelle setze ich ein rudimentäres Vorwissen von MVC voraus. Wer dieses Konzept nicht kennt, sollte sich hier belesen.

Wie andere moderne MVC-Frameworks bietet AngularJS ein sogenanntes two-way data binding. D.h., dass die Daten im Model und in der View synchron gehalten werden. Verändert man Daten im Model, sieht man diese Auswirkung sofort in der View. Umgekehrt gilt das gleiche. Was das genau bedeutet seht ihr später am Besten in der Praxis. In diesem Fall sagt eine Codezeile mehr als Tausend Worte! Two-way data binding hat lediglich einen Nachteil: Ist man es einmal gewohnt, kann man nie wieder ohne programmieren ;) Es vereinfacht den Code immens!
Das data binding von AngularJS hat eine Besonderheit. Im Vergleich zu anderen Frameworks dient ein beliebiges einfaches JavaScript-Objekt als Model. Andere Frameworks wie Ember.js verwenden stattdessen eine Art Proxy-Objekt mit einer speziellen Getter- und Setter-API. Ohne in technische Details gehen zu wollen bedeutet das im Regelfall, dass die Verwendung von AngularJS einfacher ist als andere Frameworks mit two-way data binding, aber AngularJS etwas performancehungriger ist. Der Geschwindigkeitsnachteil ist jedoch nur bei komplexen Models bemerkbar und sollte für die meisten Anwendungen nicht relevant sein. Der Performanceverlust entsteht, weil AngualrJS im sogenannten dirty checking überprüft, ob sich ein Model verändert hat. Diese Überprüfung fällt weg, wenn man eine Getter-/Setter-API verwenden würde.

Zwei weitere Konzepte zeichnen AngularJS aus. Das Framework verwendet dependency injection. D.h., das Funktionen abhängig von ihrem Namen in andere Funktionen eingeschleust werden. Dies mag sonderbar und ungewohnt klingen, aber vereinfacht den Code ebenfalls. Auch hier gilt, dass sich diese Eigenschaft später leichter im Code selbst erklären lässt.
Eine andere Besonderheit sind die Verwendung von HTML-basierten Templates und den sogenannten Direktiven. Ein Template ist eine View, die aus Platzhaltern für spätere Daten und auch aus Logik bestehen kann. In der späteren Applikationen werden die Platzhalter mit echten Daten befüllt und entsprechende Logiken ausgeführt (z.B. „Zeige diesen Button nur für registrierte Mitglieder“). Andere Frameworks verwenden String-basierte Templates (z.B. Handlebars), anstatt HTML-basierte. Die Verwendung von HTML-basierten Templates ist einfacher zu erlernen – man schreibt schließlich pures HTML – und wird von modernen IDEs von Haus aus unterstützt (Syntax-Highlighting, etc.). Es ist jedoch schwerer serverseitig zu rendern. Dies wäre zum Beispiel relevant, wenn JavaScript vom Nutzer deaktiviert wurde – auch wenn dieser Fall mittlerweile selten ist. Ein Bestandteil der HTML-basierten Templates sind die Direktiven. Einfach ausgedrückt bietet sie die Möglichkeit eigene HTML-Elemente zu entwickeln oder bestehende zu erweitern. Damit erleichtern sie die Modularität von HTML-Dokumente erheblich.

Wie ihr merkt hat AngularJS einige neue Konzepte, die es so noch nie oder kaum in der Webentwicklung gab. Ihr solltet euch die berechtigte Frage stellen, ob es sich lohnt viel Energie und Aufwand in das Erlernen dieser Konzepte zu stecken oder nicht. Ich beantworte dies mit einem einfachen ja! Das hat einen guten Grund: Diese Konzepte mögen neu sein, aber sie werden nicht wieder einfach so verschwinden. Gerade in diesem Moment werden diese Konzepte unter dem Überbegriff Web Components standardisiert. Web Components sind eine Reihe von Standards bestehend u.a. aus Object.observe, dem Shadow DOM, ES6 Module und Custom Elements. Was Direktiven für AngularJS sind, sind bspw. Custom Elements und Shadow DOM für Web Components. Da sich diese Standards noch in der Entwicklung befinden, sind sie nur schwer in realen Projekten einsetzbar. AngularJS ermöglicht es uns jedoch bereits jetzt ein Verständnis für diese Konzepte zu entwickeln und sie in realen Projekten zu verwenden. Damit erleichtert AngularJS nicht nur eure Arbeit, sondern ihr bereitet euch gleichzeitig auf die Zukunft vor.

Nun aber ein paar Code-Beispiele, die die Verwendung von AngularJS  zeigen. Installiert erst einmal AngularJS  in einen neuen Projektordner mit dem Befehl:

1
$ bower install angular

Erstellt nun eine index.html mit folgendem Inhalt. Das Beispiel ist fast vollständig von der offiziellen AngularJS-Seite übernommen:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!doctype html>
<html ng-app>
  <head>
    <script src="./bower_components/angular/angular.js"></script>
  </head>
  <body>
    <div>
      <label>Name:</label>
      <input type="text" ng-model="yourName" placeholder="Enter a name here">
      <hr>
      <h1>Hello {{yourName}}!</h1>
    </div>
  </body>
</html>

Wenn ihr die index.html in einem Browser öffnet – ihr müsst dafür nicht unbedingt auch einen Server starten – und euren Namen in das Eingabefeld eingebt, seht ihr, dass sich der Text unter dem Eingabefeld automatisch mit verändert. Dieses Beispiel zeigt two-way data binding im Einsatz. Für die gleiche Funktionalität würde man mit reinem JavaScript oder jQuery viel mehr Codezeilen benötigen. Mit AngularJS sind es im Endeffekt drei HTML-Zeilen! Zuerst wird euch im html-Element das Attribut ng-app aufgefallen sein. Attribute oder Elemente mit dem Prefix ng stammen von AngularJS. Ein ng-app im html-Element besagt, dass für das gesamte Dokument eine AngularJS-App gelten soll. Es legt das root-Element für die AngularJS App fest. Das ng-model-Attribut im input-Element stellt ein two-way data binding zu einem Model mit dem Namen yourName her. (Dieses Model wird von AngularJS automatisch erstellt.) Sobald sich der Wert im Eingabefeld ändert, ändert sich ebenfalls der Wert vom Model yourName. Das dies der Fall ist, wird mit dem Platzhalter {{yourName}} im h1-Element visualisiert. Die {{}} markieren einen beliebigen Platzhalter von Daten innerhalb eines HTML-Templates. In diesem Fall ist unser Template gleichzeitig das eigentliche Dokument. Der Bezeichner innerhalb der {{}} stimmt in diesem Fall mit unserem Model yourName überein, sodass anstelle des Platzhalters der Wert von yourName angezeigt wird. (Man könnte {{}} auch als one-way data binding ansehen, da es den Wert des Models anzeigt, er aber an dieser Stelle nicht geändert werden kann.)

Mit diesem Beispiel kratzen wir nur an der Oberfläche von AngularJS, aber es soll für den heutigen Artikel genügen. Der nächste Artikel wird sich ausführlicher mit AngularJS befassen. Beim nächsten Mal erwartet uns unser bisher größtes Code-Beispiel, darum ist es ganz gut, dass wir heute an dieser Stelle Schluss machen :)

Autor: Pipo

...kommt ursprünglich aus der Designerecke, ist aber im Laufe seines Studiums in die Webentwicklung gestolpert. Kann sich seit dem nicht so richtig entscheiden wo er hingehört und wagt deswegen vielleicht die Flucht nach vorne in ein komplett neues Gebiet. Vielleicht Management? Niemand weiß es. Auch er nicht.

Kommentare (1)

  1. Ohne in technische Details gehen zu wollen bedeutet das im Regelfall, dass die Verwendung von AngularJS einfacher ist als andere Frameworks mit two-way data binding, aber AngularJS etwas performancehungriger ist. Der Geschwindigkeitsnachteil ist jedoch nur bei komplexen Models bemerkbar und sollte für die meisten Anwendungen nicht relevant sein. Der Performanceverlust entsteht, weil AngualrJS im sogenannten dirty checking überprüft, ob sich ein Model verändert hat. Diese Überprüfung fällt weg, wenn man eine Getter-/Setter-API verwenden würde.

    Das Dirty-Checking von Angular.js hat gegenüber der Getter-/Setter-API von Ember.js was die Performance angeht übrigens nicht nur Nachteile, sondern auch einige Vorteile. Da es beim Dirty-checking nicht notwendig ist, jedes mal eine spezielle Funktion aufzurufen welche sich dann um die Änderung und Aktualisierung der Daten kümmert, werden vor Allem große Mengen an Daten mit AngularJS schneller gerendert als mit Ember.js.

    Bei der Performance des Two-Way-Data-Bindings hat Ember.js mit der Getter-/Setter-API allerdings klar die Nase vorne, da nicht erst alle Model-Variablen vor der Aktualisierung des Views geprüft werden müssen.

    Klare Unterschiede merkt man aber wie du schon geschrieben hast erst dann, wenn man sehr große Datenmengen verwendet. Dieses Performance-Benchmark zeigt die Vor- und Nachteile zwischen beiden Frameworks übrigens klar auf.

    BTW: Ich selbst bevorzuge aufgrund der Entwicklerfreundlichkeit und Eleganz grundsätzlich AngularJS. Auch die Sache mit den Templates finde ich in AngularJS deutlich besser gelöst als in Ember.js.