Ein Modul für alle Fälle

So löst man mit AngularJS-Modulen Probleme bei der Webapp-Entwicklung
Keine Kommentare

AngularJS ist momentan eines der populärsten JavaScript-Frameworks, wenn es darum geht, umfangreiche Webapplikationen zu erstellen. Und genau da fangen die Probleme an. AngularJS ist lediglich das Basisframework und bietet Ihnen eine Reihe von Hilfsmitteln. Dies geht allerdings nur begrenzt weit, denn das Framework stellt keine Universallösung für sämtliche Probleme dar. Allerdings können einige dieser Schwierigkeiten mit verschiedenen AngularJS-Modulen bearbeitet werden.

AngularJS sieht einen modularen Aufbau von Applikationen vor, sodass es ein Leichtes ist, wiederverwendbare Komponenten zu erstellen. So hat sich um das Framework eine rege Community gebildet, die sehr aktiv an der Entwicklung verschiedenster Erweiterungen arbeitet. Im Zuge dieses Artikels möchte ich Ihnen einige der häufigsten Problemstellungen bei der Entwicklung von Webapplikationen und die dazu passenden Angular-Module vorstellen.

Einbindung von Modulen

Die Vorgehensweise bei der Einbindung externer Module ist stets – bis auf einige modulspezifische Besonderheiten – die gleiche. Zunächst müssen Sie sich das Modul herunterladen. Diese Aufgabe können Sie sich vereinfachen, wenn Sie den Paketmanager Bower verwenden, dessen Installation und Verwendung in der Dokumentation des Werkzeugs detailliert beschrieben wird. Haben Sie Bower installiert, müssen Sie nur noch den Namen des zu installierenden Pakets kennen. Das Herunterladen und Speichern übernimmt dann Bower für Sie. Ein weiterer Dienst, den Ihnen Bower bietet, ist die Auflösung von Abhängigkeiten. Wird beispielsweise für ein bestimmtes Modul die jQuery-Bibliothek benötigt, sorgt Bower dafür, dass diese ebenfalls heruntergeladen wird. Egal, ob Sie die Angular-Module mit oder ohne Bower installieren, wichtig ist nur, dass die erforderlichen Dateien auf Ihrem Server verfügbar sind.

Nachdem Sie die Dateien heruntergeladen und in Ihrer Applikation gespeichert haben, müssen Sie die Dateien mittels eines script-Tags in Ihre Seite einbinden. Wächst Ihre Applikation und strukturieren Sie sie über mehrere Dateien hinweg, benötigen Sie sehr viele script-Tags, was früher oder später unübersichtlich werden kann. Hinzu kommt, dass in manchen Fällen die Reihenfolge der script-Tags eine Rolle spielt. So muss AngularJS geladen sein, bevor Sie ein Angular-Modul einbinden. Ein Hilfsmittel, das Sie bei diesen Problemen unterstützt, ist RequireJS. Diese kleine Bibliothek bietet Ihnen einen Modul-Loader, der sich darum kümmert, alle benötigten Dateien zu laden und Abhängigkeiten unter den Dateien aufzulösen. Als Bonus erhalten Sie außerdem noch einen Optimizer, der Ihre JavaScript-Applikation und sämtliche Bibliotheken zu einer einzigen Datei zusammenfasst, diese optimiert und sämtliche unnötigen Zeichen entfernt. Auch hier gilt: RequireJS wird nicht zwingend benötigt, wenn Sie Applikationen mit AngularJS bauen, es erleichtert Ihnen lediglich die Arbeit.

Die meisten Angular-Module werden durch einen Aufruf von angular.module erstellt. Das bedeutet, dass Sie das Modul ganz einfach einbinden können, indem Sie seinen Namen bei Ihrer eigenen Moduldefinition angeben. Trägt Ihre Applikation beispielsweise den Namen app und Sie möchten den Angular-ui-Router einbinden, führt das zu folgendem Aufruf: angular.module(‚app‘, [‚ui.router‘]);.

Nach Abschluss dieser Schritte können Sie das Modul verwenden. Damit sind wir bei der ersten Aufgabenstellung angelangt: Wie können Sie aus einer Angular-Applikation heraus mit einem Server kommunizieren?

REST-Kommunikation zum Server

AngularJS bietet Ihnen einen Service mit dem Namen $http. Dieser dient zur asynchronen Kommunikation mit dem Server. Den $http-Service können Sie sich als eine Abstraktion des XMLHttpRequest-Objekts vorstellen, mit dem Sie HTTP-Aufrufe an Ihr Backend absetzen können. Dieser Service hat zwei Gründe. Zum einen bietet er Ihnen eine angenehme und einheitliche Schnittstelle, zum anderen können Sie ihn zu Testzwecken ganz einfach austauschen und benötigen so kein umfangreiches Serversystem zum Testen. Die meisten modernen Webapplikationen nutzen jedoch nicht nur die Methoden GET und POST, sondern versuchen, per REST mit dem Server zu sprechen. Ob es sich bei dieser Kommunikation um wirkliches REST wie aus dem Lehrbuch oder eine Abwandlung davon handelt, führt zwar oft zu leidenschaftlichen Diskussionen, hat allerdings wenig Auswirkungen auf den Einsatz der hier vorgestellten Module.

Wie so oft in der Webentwicklung gibt es nicht nur einen Weg zum Ziel. So ist es auch hier. In der Angular-Community gibt es zwei populäre Module für die REST-Kommunikation mit dem Server: ngResource und Restangular.

ngResource: Das ngResource-Modul wird von den Entwicklern von AngularJS selbst entwickelt, ist allerdings dennoch ein eigenständiges Modul, das Sie separat einbinden müssen. Installiert wird es mit Bower über den Befehl bower install angular-resource; anschließend binden Sie es in Ihr Modul über den Namen ngResource ein.

Den Kern von ngResource bildet ein Service, den Sie Ihren Anforderungen entsprechend konfigurieren können. Sie können ngResource entweder direkt verwenden oder eigene Services für Ihre Ressourcen definieren, die dann die gesamte Konfiguration enthalten. Generell ist es empfehlenswert, Ressourcen in eigenen Dateien zu verwalten.

Der von ngResource zur Verfügung gestellte Service akzeptiert folgende vier Parameter, von denen allerdings nur der erste zwingend erforderlich ist:

  • url: Dies ist der URL, der auf dem Server angesprochen werden soll. Platzhalter im URL werden durch einen vorangestellten Doppelpunkt gekennzeichnet, z. B. ‚/user/:userId.
  • paramDefaults: Dieses Objekt dient zur Befüllung der Platzhalter im URL. Wird dem Wert ein @-Zeichen vorangestellt, wird er direkt aus dem später übergebenen Objekt genommen. Ansonsten werden einfach die Platzhalter durch die entsprechenden Werte des Objekts ersetzt, beziehungsweise übrige Werte als Querystring an den URL angehängt.
  • actions: Mit diesem Objekt werden die verfügbaren Methoden des resultierenden Ressourcenobjekts konfiguriert. Die Standardmethoden sind: get, save, query, remove und delete. Geben Sie hier ein Objekt an, werden die Standardmethoden überschrieben. Sie können hier unter anderem die HTTP-Methode angeben und ob es sich bei der Antwort des Servers um ein Array oder ein einzelnes Objekt handelt.
  • options: Mit diesem Objekt können die Schrägstriche am Ende der Anfrage automatisch entfernt werden.
angular.module('todo.resource', ['ngResource'])
  .factory('todoResource', todoResource);

todoResource.$inject = ['$resource'];

function todoResource($resource) {
  return $resource(
    '/todo/:id',
    {id: '@id'},
    {
      findOne: {method: 'GET', isArray: true},
      findAll: {method: 'GET', isArray: true},
      create: {method: 'POST'},
      update: {method: 'PUT'},
      remove: {method: 'DELETE'}
    }
  );
}

Wie bereits erwähnt, ist ngResource nicht die einzige Lösung für dieses Problem. Das Modul Restangular versucht, einige Nachteile von ngResource zu umgehen und stellt aus diesem Grund eine ernstzunehmende Alternative dar.

Restangular: Die Installation von Restangular ist ähnlich einfach wie die von ngResource. Sie müssen lediglich den Befehl bower install restangular ausführen, die Datei laden und schließlich das Modul unter dem Namen Restangular einbinden.

Im ersten Schritt müssen Sie, wie bei ngResource, Ihre Ressource konfigurieren. Diese Konfiguration erfolgt ebenfalls über einen von Restangular zur Verfügung gestellten Service. Laden Sie den Service unter dem Namen Restangular über den Dependency-Injection-Mechanismus von Angular, können Sie eine Ressource mit dem Basis-URL user einfach mit einem Aufruf von Restangular.all(‚user‘) erstellen. Über das resultierende Objekt können Sie dann mit dem Server kommunizieren. Neben all können Sie auch one oder several verwenden, um nur auf ein bestimmtes Objekt oder eine bestimmte Gruppe von Objekten zugreifen zu können.

Um sämtliche Benutzerobjekte vom Server zu laden, rufen Sie auf dem Rückgabewert von Restangular.all die Methode getList auf. Weitere Methoden sind:

  • post, zum Neuanlegen eines Objekts
  • put, um ein Objekt zu verändern
  • remove, um ein Objekt zu löschen

Restangular bietet Ihnen noch eine Vielzahl weiterer Optionen, die Sie am besten der Onlinedokumentation entnehmen.

Ein wichtiger Unterschied zu ngResource ist, dass Restangular verschachtelte Ressourcen unterstützt. Hat ein Userobjekt beispielsweise eine Adresse, könnte eine mögliche Abfrage folgendermaßen aussehen: Restangular.one(‚user‘, 1).one(‚address‘, 3).get(). Diese führt dazu, dass der Datensatz hinter dem URL /user/1/address/3 mit einer GET-Anfrage geladen wird.

Außerdem arbeitet Restangular direkt mit Promises, wodurch Sie den Aufruf der then-Methode direkt an ein getList hängen und entsprechende Callback-Funktionen für Erfolg und Misserfolg definieren können.

Restangular.all('todo').getList()
  .then(function(todos) {
  vm.todo= todos[0];
});

Soviel zum Thema REST-Ressourcen in AngularJS. Auch das nächste Thema betrifft einen Großteil der Entwickler von Single-Page-Applikationen: Routing.

Routing

Zunächst stellen Sie sich wahrscheinlich die Frage, was man im Kontext von AngularJS unter Routing versteht. Kurz zusammengefasst bezeichnet Routing die Navigation innerhalb einer Single-Page-Applikation, ohne dass die Seite im Browser neu geladen wird. Die Navigation erfolgt in den meisten Fällen über einen Teil des URL, den so genannten Hash. Dieser ist durch ein #-Zeichen vom übrigen URL getrennt. Eine Änderung hier führt nicht zum Neuladen der Seite. Eigentlich ist der Hash im URL dazu gedacht, um zu bestimmten Ankerpunkten auf der Seite zu springen. Die Änderung des Hashes kann allerdings auch für die Navigation benutzt werden. In JavaScript wird bei jeder Änderung ein Event ausgelöst, auf das eine Callback-Funktion registriert werden kann.

Mit dieser Art des Routings können Sie bestimmte Teile Ihrer Applikation aktualisieren, ohne dass die komplette Seite neu geladen werden muss. Da die Navigation über den URL erfolgt, können diese URLs auch kopiert oder später als Bookmark wiederverwendet werden. Der URL reflektiert in diesem Fall einen bestimmten Status der Applikation.

Auch für das Routing in AngularJS-Applikationen gibt es mehrere Lösungen. Zwei relativ populäre sind ngRoute und der ui-router.

ngRoute: Der ngRouter ist eine Ausgliederung der Routing-Funktionalität aus dem Kern von AngularJS. Dieses Modul wird durch das Kommando bower install angular-route installiert. Die Einbindung erfolgt über den Namen ngRoute. Bei ngRoute handelt es sich um einen Provider, also einen konfigurierbaren Service in AngularJS. Die Konfiguration erstellen Sie innerhalb Ihrer Applikation über die config-Methode von Angular. Mit dieser haben Sie Zugriff auf den routeProvider, auf dem Sie die einzelnen Routen Ihrer Applikation erstellen.

Eine Route sollte zumindest aus einem Controller und einem Template bestehen. Der Controller ist der Einstiegspunkt für die Logik, die hinter dieser Route liegt und hält das View Model, das entweder das $scope-Objekt sein oder über controllerAs verwaltet werden kann. Das Template stellt dabei die HTML-Struktur zur Verfügung. Zur Konfiguration der Route rufen Sie die when-Methode auf dem routeProvider auf. Das erste Argument ist der Name der Route, also zum Beispiel /User/:uid, wobei alle Angaben, denen ein Doppelpunkt vorangestellt sind, einen Platzhalter darstellen. Das zweite Argument ist das eigentliche Konfigurationsobjekt. Die wichtigsten Angaben, die Sie hier machen können, sind:

  • controller: Der Name des Controllers, der für diese Route gültig sein soll.
  • controllerAs: Der Name, der für den Controller im Template verwendet werden soll.
  • template: Eine Zeichenkette, die eine HTML-Struktur enthält, die durch die Route dargestellt werden soll. Alternativ kann auch eine Funktion verwendet werden, die eine HTML-Zeichenkette zurückgibt.
  • templateURL: URL zur Datei, die das Template beinhaltet.
  • resolve: Objekt, das dazu verwendet werden kann, um Werte in den Controller der Route zu injizieren.

Haben Sie Ihre Routen konfiguriert, benötigen Sie noch einen Ankerpunkt, an dem Sie die Templates einfügen, wenn eine Route aktiviert wird. Zu diesem Zweck nutzen Sie die ng-view-Direktive aus dem ngRoute-Modul, die Sie am besten in ein Block-Element wie ein div einfügen. Um eine Route auszuwählen, können Sie nun wie gewohnt auf a-Tags zurückgreifen. Der Link beginnt hier jedoch mit einem Hash-Zeichen, um einen Seitenreload zu vermeiden.

Jetzt stellt sich noch die Frage, wie Sie auf die Variablen in Ihrer Route zugreifen können, um die Logik zu beeinflussen. Binden Sie den $routeParams-Service per Dependency Injection in Ihren Controller ein, können Sie über den Namen der Variablen, die Sie in der Konfiguration der Route vergeben haben, darauf zugreifen.

angular.module('app', ['ngRoute'])
  .config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/todo', {
    templateUrl: 'templates/todoList.html',
    controller: 'TodoListController'
  })
}]);

In der Routingkonfiguration können Sie durch einen Aufruf der otherwise-Methode des $routeProviders mit der Angabe von redirectTo im Konfigurationsobjekt definieren, wohin Sie weiterleiten möchten, falls aktuell keine Route zutrifft. Mit dieser Option können Sie eine Standardroute definieren.

Ein letztes Feature, das ich Ihnen hier vorstellen möchte, ist die manuelle Änderung der Route innerhalb der JavaScript-Logik Ihrer Applikation. Hierfür müssen Sie den $location-Service benutzen und können dann über einen Aufruf der path-Methode unter Angabe der neuen Route diese aktivieren.

ui-router: Der ui-router entstammt dem AngularUI-Projekt, das Ergänzungen und Erweiterungen für AngularJS zur Verfügung stellt. Der ui-router greift die Ideen von ngRoute auf und ergänzt und erweitert die Funktionalität. Grundsätzlich bietet der ui-router alle Features von ngRoute. Zusätzlich bringt der ui-router die Unterstützung verschachtelter Views und mehrere benannter Views mit. Damit lassen sich Routen wesentlich detaillierter steuern und so auch Teile der Applikation unabhängig voneinander oder parallel ansteuern.

Die Konfiguration der Routen findet, wie bei ngRoute, im config-Block der Applikation über den $stateProvider statt. Die Routen werden durch Aufrufe der state-Methode definiert. Jede state hat eine Bezeichnung und ein URL. Hinzu kommen Controller und Template, die wie bei ngRoute definiert werden können.

Der ui-router definiert neben dem Routingservice zusätzliche Direktiven, die Sie in Ihren Templates nutzen können. Analog zum ng-view stellt Ihnen der ui-router die Direktive ui-view zur Verfügung, um die Inhalte der jeweiligen Routen darzustellen. Sie können dieser Direktive einen Wert zuweisen, der dann als Name des Elements verwendet wird und bei benannten Routen zum Einsatz kommt. Die zweite wichtige Direktive ist ui-sref. Mit dieser Direktive können Sie Routen aktivieren. ui-sref können Sie verwenden wie das bekannte href-Attribut bei Links.

angular.module('app', ['ui.router'])
  .config(['$stateProvider', '$urlRouterProvider',
          function($stateProvider, $urlRouterProvider) {
  $stateProvider
    .state('todo', {
    url: "/todo",
    templateUrl: "templates/todoList.html",
    controller: 'TodoListController'
  });
}]);

Mit dem ui-router wird versucht, eine Applikation durch eine State Machine zu organisieren und durch den Router zwischen den verschiedenen Zuständen der Applikation zu wechseln.

Nachdem Sie mit ngRoute oder dem ui-router zwei sehr gute Lösungen für die Navigation in einer Single-Page-Applikation kennengelernt haben, wird es nun Zeit, sich dem nächsten Problem zu widmen: der Mehrsprachigkeit von Applikationen.

Übersetzungen

Eine Anforderung bei vielen Applikationen lautet, dass sie in mehreren Sprachen verfügbar sein soll ¬ man will ja schließlich keine potenziellen Kunden von vornherein ausschließen. Dieses Problem ergibt sich auch bei Applikationen, die mit AngularJS umgesetzt werden. Eine einfache Lösung ist, die Übersetzung serverseitig durchzuführen und dem Browser nur fertig übersetzte Inhalte auszuliefern. Das bedeutet allerdings auch, dass ein Umschalten der Sprache einen Reload der Seite zur Folge hat, was für eine Single-Page-Applikation ein No-Go ist. Mit angular-translate lässt sich aber auch dieses Problem auf elegante Weise lösen.

angular-translate: angular-translate ist ein eigenständiges Modul, das per Bower über den Namen angular-translate installiert und über pascalprecht.translate in die Applikation eingebunden werden kann.

angular-translate besteht aus Direktiven, Filtern und Services und bettet sich so nahtlos in Ihre Applikation ein. Die Grundlage bildet die Konfiguration der Übersetzungen, auf der die übrigen Komponenten aufbauen. Die Konfiguration findet in einem config-Block in Ihrer Applikation statt, in dem Sie den $translateProvider mit den verfügbaren Übersetzungen bestücken. Pro Sprache sollte es ein Objekt geben, dessen Schlüssel die zu übersetzenden Zeichenketten und die Werte die jeweiligen Übersetzungen sind. Außerdem können Sie eine Standardsprache einsetzen. Für sehr große Applikationen ist es wenig praktikabel, sämtliche Übersetzungen direkt im Quellcode der Applikation vorzunehmen. Die Sprachdateien können entweder asynchron nachgeladen oder durch einen Modul-Loader wie beispielsweise RequireJS in separate Dateien ausgelagert werden.

angular.module('app', ['pascalprecht.translate'])
  .config(['$translateProvider', function ($translateProvider) {
  $translateProvider.translations('en', {
    SAVE: 'save'
  });
  $translateProvider.translations('de', {
    SAVE: 'speichern'
  });
  $translateProvider.preferredLanguage('en');
}]);

<button>{{ 'SAVE' | translate }} </button>

Die einfachste Variante der Übersetzung ist der Einsatz des translate-Filters direkt im Template. Die Verwendung von großgeschriebenen Zeichenketten hat sich als Best Practice im Zusammenhang mit Übersetzungen herausgebildet, da in diesem Fall sofort auffällt, wenn eine Zeichenkette noch nicht übersetzt ist.

Um die Übersetzungen so flexibel wie möglich zu halten, können Sie auch Variablen verwenden. Zu diesem Zweck müssen Sie eine Expression innerhalb der Übersetzung definieren und können dann den Wert dieses Platzhalters durch die Übergabe eines Werts beispielsweise im Filter füllen.

Neben dem bereits erwähnten Filter gibt es außerdem noch die Möglichkeit, Übersetzungen in Direktiven zu kapseln. Die Direktive trägt den Namen translate und kann sowohl als Element, als auch als Attribut angewandt werden. Die zu übersetzende Zeichenkette wird entweder als Attributwert oder als Inhalt der Direktive angegeben.

Möchten Sie die Übersetzung allerdings innerhalb Ihrer JavaScript-Logik vornehmen, können Sie entweder wieder auf den Filter zurückgreifen oder den $translate-Service verwenden.

Der Funktionsumfang von angular-translate endet hier jedoch noch nicht. Das Modul unterstützt auch Pluralisierung, indem die Funktionalität von MessageFormat adaptiert wird. Weitere Informationen über den Funktionsumfang von angular-translate finden Sie in der Onlinedokumentation.

AngularJS spielt seine Stärken vor allem in Applikationen aus, bei denen es darum geht, Daten zu verwalten. Im folgenden Abschnitt lernen Sie einige Module kennen, die hilfreich sind, wenn es um die Darstellung von Informationen geht.

Tabellen

Hat man in einer Applikation mit Daten zu tun, die verwaltet werden müssen, ist der Startpunkt meist eine tabellarische Auflistung der Daten, oder zumindest eines Teils der Daten. Bei der Anzeige kommt meist ein Schleifenkonstrukt zum Einsatz. Angular bringt hierfür die Direktive ng-repeat mit. In Kombination mit Filtern sind Sie dann in der Lage, die Liste zu sortieren und zu filtern. Danach arbeiten Sie noch etwas am Styling und die Aufgabe ist gelöst. Aufbauend auf diesem Konstrukt kommen schnell weitere Anforderungen wie Paginierung oder Ähnliches auf, die die Lösung zunehmend komplexer werden lassen.

Mit dieser oder einer sehr ähnlichen Aufgabenstellung wird man recht häufig konfrontiert, sodass es sich nicht lohnt, die Lösung jedes Mal wieder von neuem zu entwickeln. Aus diesem Grund gibt es auch etliche Module, die diese Aufgaben lösen.

UI Grid: Das UI Grid ist ein Datengrid mit großem Funktionsumfang, das die meisten Standardaufgaben bereits bedient. Die Installation ist problemlos über Bower über den Paketnamen angular-ui-grid möglich. Die Einbindung erfolgt über den Modulnamen ui.grid. Wie der Name bereits erahnen lässt, stammt dieses Modul aus dem Angular-UI-Projekt. Um dieses Modul verwenden zu können, benötigen Sie jQuery, das Sie vor Angular und UI Grid laden müssen. Außerdem müssen Sie die Datei ui-grid.css laden und damit den Style anwenden, damit das Grid verwendbar wird.

Um mit der Benutzung des UI Grids zu starten, müssen Sie lediglich die UI-Grid-Direktive in Ihrer View verwenden. Diese Direktive erhält ein Konfigurationsobjekt, das Sie entweder direkt als Attributwert in der View übergeben oder besser noch als Variable im Controller definieren. Die einzige Option, die Sie zwingend zur Verfügung stellen müssen, ist data, mit der Sie angeben, welche Daten Sie im Grid anzeigen möchten. Die Daten liegen als Array von Objekten vor. Die Schlüssel sind dabei die Spaltennamen des Grids; die Daten werden in den Zellen angezeigt. Optional können Sie eine Spaltendefinition im Konfigurationsobjekt angeben.

Das Datengrid ist standardmäßig in jeder Spalte sortierbar. Sie können den Algorithmus für jede Spalte individuell definieren, falls der Standard nicht ausreicht.

$scope.gridOptions = {
  data: $scope.myData,
  enableFiltering: true,
  pagingPageSize: 2
};

<div ui-grid="gridOptions" ui-grid-pagination></div>

Sie können das Datengrid außerdem filtern. Zu diesem Zweck müssen Sie lediglich die Option enableFiltering auf true setzen. Dies können Sie entweder global für das gesamte Grid oder auch nur für bestimmte Spalten tun. Ist die Filterung aktiviert, erscheint im Tabellenkopf ein Eingabefeld. Geben Sie hier Werte ein, wird das Grid in Echtzeit gefiltert. Standardmäßig beginnt der Filter am Zeilenanfang. Sie können jedoch auch benutzerdefinierte Filter anwenden.

Das UI Grid bringt neben diesen grundlegenden Features auch noch eine Vielzahl weiterer Optionen mit. Dazu zählen Paginierung, die Sie per Option anschalten können, oder die Möglichkeit, Zellen zu editieren und die Daten zu speichern.

Erfreulich beim UI Grid ist außerdem die Performance. Auch bei über 10 000 Datensätzen ist die Applikation noch gut zu bedienen.

Auch wenn das UI Grid schon eine gute Wahl ist, ist es dennoch nicht das einzige Modul, wenn es um die Anzeige von Informationen in Tabellenform geht. Eine weitere Option ist das Smart-Table-Modul.

Smart Table: Die Installation dieses Moduls erfolgt per Bower über den Namen angular-smart-table, die Einbindung über Smart Table. Verwenden Sie Smart Table, müssen Sie etwas mehr View-Code schreiben als bei UI Grid. Dafür sind Sie hier aber auch wesentlich flexibler. Der Aufbau einer Smart Table ist relativ einfach: Sie definieren eine einfache HTML-Tabelle und fügen in das table-Tag die Direktive st-table mit dem Namen des Objekts, das die Daten enthält, als Wert ein. Mit den Direktiven st-search und st-sort aktivieren Sie den Filter beziehungsweise die Sortierung der Smart Table. Die Direktive st-pagination sorgt für die Aktivierung der Paginierung der Smart Table. Insgesamt bietet die Smart Table etwas weniger Features als das UI Grid. Mit etwas mehr Aufwand lassen sich allerdings auch hier umfangreiche und komplexe Features sehr gut umsetzen.

<table st-table="users" class="table table-striped">
  <thead>
    <tr>
      <th st-sort="name">first name</th>
      <th st-sort="age">last name</th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="row in users">
      <td>{{row.name}}</td>
      <td>{{row.age}}</td>
    </tr>
  </tbody>
</table>

Von der Darstellung von Informationen kommen wir im letzten Abschnitt nun zum Thema der Datenspeicherung im Client und dem generellen Umgang mit externen Schnittstellen.

Datenspeicher

Mit HTML5 eröffnen sich durch zahlreiche JavaScript-APIs neue Möglichkeiten für Entwickler. So bieten beispielsweise localStorage und sessionStorage einen Mechanismus zur Datenspeicherung im Browser. Es ist allerdings kein guter Stil, diese APIs direkt anzusprechen. Angular selbst demonstriert den Umgang mit Browserschnittstellen am Beispiel der Funktionen setTimeout und setInterval, die in Angular als $timeout und $interval verfügbar sind. Diese Abstraktionsschicht hat zweierlei Bedeutung: Zum einen wird hier die $apply-Funktion ausgeführt, zum anderen können diese Implementierungen zu Testzwecken leicht ausgetauscht werden. Gerade vor dem Hintergrund der guten Testbarkeit sollten Sie auch für localStorage nicht die Browserschnittstelle direkt verwenden, sondern stattdessen auf existierende Angular-Module zurückgreifen.

ngStorage: Eines der am häufigsten verwendeten Module, wenn es um localStorage geht, ist ngStorage. Dieses Modul lässt sich, wie die übrigen bereits vorgestellten Module, über Bower installieren. Verwenden Sie hierfür den Paketnamen ngstorage. Eingebunden wird das Modul über den Namen ngStorage.

Haben Sie das Modul erst eingebunden, können Sie auf die zwei Services $localStorage und $sessionStorage zugreifen.

angular.module('app', ['ngStorage'])
  .controller('myCtrl', ['$localStorage', function($localStorage){
  $localStorage.default({
    name: 'Klaus'
  });

  // ...

  $localStorage.name = 'Lisa';
}]);

Schreiben und lesen können Sie über einfachen Objektzugriff auf die Struktur des jeweiligen Service. Mit der Funktion $default können Sie außerdem Standardwerte vordefinieren.

Einzelne Datensätze lassen sich mit dem delete– Schlüsselwort löschen, den kompletten local– beziehungsweise sessionStorage leeren Sie mit einem Aufruf der $restore-Funktion auf dem jeweiligen Service.

Fazit

Sie haben gesehen, dass Sie bei der Erstellung von Applikationen mit Angular nicht auf sich allein gestellt sind. Sie können auf eine große Menge vordefinierter Module zurückgreifen, die Ihnen verschiedenste Komponenten bieten, die Sie problemlos in Ihre Applikation integrieren können. Mit dieser Vorgehensweise ersparen Sie sich viel Schreibarbeit und Entwicklungszeit. Außerdem sind einige Module bereits seit längerer Zeit auch in großen Applikationen im Einsatz und weitestgehend fehlerfrei. Auch wichtige Themen wie Performance, die Abdeckung mit Unit Tests oder eine ausführliche Dokumentation werden bei externen Modulen ernst genommen, sodass Sie sich nicht selbst darum kümmern müssen.

Greifen Sie bei der Installation auf Bower zurück, werden Ihnen die Auflösung eventueller Abhängigkeiten, Updates und der Umgang mit verschiedenen Versionen abgenommen. Bleibt nur noch die Frage, wie Sie die für Sie passenden Module finden. Eine erste Anlaufstelle ist natürlich Ihre Suchmaschine, in der Sie das gesuchte Feature im Kontext von Angular suchen sollten. Die Bewertung der Ergebnisse ist recht einfach, wenn Sie sich eine Reihe von Fragen stellen:

  • Ist das Modul mit der verwendeten Version von Angular kompatibel?
  • Ist das Modul Open Source?
  • Wird das Modul aktuell gepflegt? Wann war der letzte Commit, wann wurde der letzte Issue gelöst?
  • Existiert eine umfangreiche und verständliche Dokumentation, am besten mit Beispielen?
  • Gibt es Tests für das Modul?

Eine weitere Anlaufstelle ist die Webseite ngmodules.org. Hier finden Sie eine Liste von Modulen mit einer kurzen Beschreibung und einer Zahl, wie viele der Nutzer das jeweilige Modul verwenden, wobei die Zahlen nicht die wirklichen Nutzungsstatistiken wiedergeben, sondern lediglich Angaben von Nutzern der Plattform sind.

Egal, wie Sie Ihre Module suchen und finden, es lohnt sich meist, einige Zeit in die Recherche zu investieren, da Ihnen die Module die Arbeit erheblich erleichtern.

PHP Magazin

Entwickler MagazinDieser Artikel ist im PHP Magazin erschienen. Das PHP Magazin deckt ein breites Spektrum an Themen ab, die für die erfolgreiche Webentwicklung unerlässlich sind.

Natürlich können Sie das PHP Magazin über den entwickler.kiosk auch digital im Browser oder auf Ihren Android- und iOS-Devices lesen. In unserem Shop ist das Entwickler Magazin ferner im Abonnement oder als Einzelheft erhältlich.

Urheberrecht: Conceptual image of a businessman holding big hammer von Shutterstock.com / Urheberrecht: conrado

Unsere Redaktion empfiehlt:

Relevante Beiträge

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu:
X
- Gib Deinen Standort ein -
- or -