Große Applikationen
mit
WHO AM I?
• Sebastian Springer
• aus München
• arbeite bei Mayflower
• https://github.com/sspringer82
• @basti_springer
• C...
Konventionen
Wenn ihr heute nur einen Punkt mitnehmt, dann:
Haltet euren Code und eure Struktur einheitlich.
Was ist eine
große Applikation?
K. Bangwa / pixelio.de
Großer
Funktionsumfang
Grundsätzliches
Bernd Kasper / pixelio.de
Sprechender Code
Sprechender Code
angular.module('myApp', [])

.controller('MyCtrl', MyCtrl);





function MyCtrl() {

var vm = this;



v...
Sprechender Code
Was ist, wenn ein Funktionsname zu lange wird?
Dann macht die Funktion wahrscheinlich zu viel und sollte
...
Komplexität
Tim Reckmann / pixelio.de
Komplexität
Applikation in kleinere, weniger komplexe Einheiten unter-
teilen und diese zu einem Komplettsystem integriere...
Komplexität
vm.start = function() {

vm.status = "started";



stopInterval = $interval(function () {



var data = reader...
Styleguide
Styleguide
Der Quellcode soll überall gleich aussehen.
Dem Quellcode soll man nicht ansehen, wann er von wem mit
welcher L...
Werkzeuge
Gila Hanssen / pixelio.de
Entwicklungsumgebung
Entwicklungsumgebung
Autocompletion: Variablen und Konstrukte vervollständigen.
Hilfestellung bieten.
Highlighting: Visuel...
Entwicklungsumgebung
Paketverwaltung
Rainer Sturm / pixelio.de
Paketverwaltung
Installation externer Bibliotheken. Versionsverwaltung und
Überblick über installierte Bibliotheken. Auflös...
Paketverwaltung
$ bower install angular
bower angular#* cached git://github.com/angular/bower-a
bower angular#* validate 1...
Yeoman
Scaffolding für Webprojekte. Bietet Generatoren, um schnell
häufig benötigte Strukturen im Projekt zu schaffen.
Yeoman
npm install -g yo
npm install -g generator-angular
yo angular myApp
yo angular:controller account
Yeoman
Problem:
Aber unsere Applikation ist etwas ganz besonderes und die
bestehenden Generatoren passen für uns nicht. Wi...
Struktur
Initiative Echte Soziale Marktwirtschaft IESM / pixelio.de
Struktur
Wie baut man eine Applikation auf, damit sie wartbar und
erweiterbar bleibt?
Wo findet man bestimmte Komponenten?
...
Ein Verzeichnis pro
Feature
Ein Verzeichnis pro Feature
Features unabhängig halten. Wiederverwendbarkeit in
anderen Applikationen erreichen. Klares Na...
Ein Verzeichnis für
shared content
Ein Verzeichnis für shared
content
Gemeinsam genutzte Komponenten liegen in einer eigenen
Hierarchie. Abhängigkeiten zwisc...
Eine Komponente pro
Datei
Eine Komponente pro Datei
Controller, Services, Direktiven, … erhalten jeweils ihre eigene
Datei.
Single Responsibility - ...
Eine Komponente pro Datei
angular.module('user.controller.login', [])

.controller('user.loginController', LoginController...
Einheitliche sprechende
Benennung
Einheitliche sprechende
Benennung
Die Namen von Dateien und deren Speicherort folgt einem
konsistenten Schema.
Das Lokalis...
Konfiguration
auslagern
Konfiguration auslagern
Die Konfiguration eines Moduls liegt in einer eigenen Datei
innerhalb des Moduls.
Die Konfiguration e...
Konfiguration auslagern
angular.module('addressBook.translation', ['pascalprecht.translate'])

.config(['$translateProvider...
Struktur flach halten
Struktur flach halten
Die Verzeichnisstruktur sollte initial möglichst flach sein. Bei
Bedarf (viele Dateien pro Verzeichnis...
Routing
Erich Westendarp / pixelio.de
Routing
Navigation zwischen verschiedenen States in der
Applikation.
States arbeiten mit Views, die benannt sein können. O...
Routing - Konfiguration
angular.module('adress', ['ui.router'])

.config(ConfigFn);



ConfigFn.$inject = ['$stateProvider'...
Routing - advanced
Mehrere benannte Views
<body>

<div ui-view="content"></div>

<div ui-view="info"></div>

</body>
$stat...
Routing - advanced
<div ui-view></div>

<a ui-sref="state1">State 1</a>
<a ui-sref="state1.list">Show List</a>

<div ui-vi...
Routing - advanced
Nested Views
$stateProvider

.state('state1', {

url: "/state1",

templateUrl: "partials/state1.html"

...
Routing - new Router
Redesignter Router. Folgeversion von ngRoute. Aktuell noch
nicht stabil. Ist aber für 1.4 und 2 vorge...
DRY
Don’t Repeat Yourself
DRY
Sobald eine Routine zum zweiten Mal implementiert wird,
sollte sie in einen eigenständigen Service ausgelagert
werden....
DRY
Nützliche Helper können in einer eigenen Library gesammelt
werden.
z.B. Logger
NIH
Not Invented Here
NIH
Bevor man etwas selbst implementiert, sollte man zuerst
prüfen, ob es für diese Problemstellung nicht schon eine
Lösun...
Dokumentation
René Golembewski / pixelio.de
Dokumentation
Es muss nicht jede Funktion dokumentiert werden (z.B.
Callbacks)
Lieber sprechenden Code schreiben.
Dokumentation
Schnittstellen zwischen Teams/Projekten müssen
dokumentiert und AKTUELL gehalten werden.
Dokumentation
Angular selbst verwendet jsdoc bzw. ngdoc und Dgeni zum
Parsen.
Weitere Infos:
https://github.com/angular/an...
Dokumentation
/**

* @name trim

* @private

*

* @description

* trim polyfill

*

* @returns {string} The string strippe...
Typescript
Zur Dokumentation von Schnittstellen kann zusätzlich
Typescript eingesetzt werden.
Möglichkeit zur Beschreibung...
Code
Corinna Dumat / pixelio.de
Struktur vs.
Implementierung
Struktur vs. Implementierung
Trennung der konkreten Implementierung und der Struktur.
Rückgabe/Bindables getrennt von den
...
Struktur vs. Implementierung
function ListCtrl() {

var vm = this;



vm.onEdit = onEdit;

vm.onDelete = onDelete;



func...
init-Funktion
init-Funktion
Sämtliche Logik, die in einem Controller zur Initialisierung
direkt ausgeführt wird, wird in einer Funktion ...
init-Funktion
function ListCtrl(itemStore) {

var vm = this;



vm.items = [];



function init() {

itemStore.fetch().the...
Logik in Services
Logik in Services
Controller sollten nicht zu viel Logik beinhalten, da sie
dadurch unleserlich werden. Umfangreichere Log...
Ein Controller pro View
Ein Controller pro View
Mehrere Views sollten sich nicht einen Controller teilen. Dies
macht es meistens erforderlich, Log...
Promises
JMG / pixelio.de
Promises
Promises sind ein Mittel, um asynchronen Programmfluss zu
steuern. Sie erhöhen die Lesbarkeit des Quellcodes und
h...
Promises
ListCtrl.$inject = ['$q', '$timeout'];



function ListCtrl($q, $timeout) {



function async() {

return $q(func...
Testing?
Rike / pixelio.de
Tests
Mindestens zwei Ebenen von Tests: Unittests und End2End-
Tests.
Manuelle Tests können allerdings nicht entfallen, da...
Unittests
Unittests
Karma: bietet die Infrastruktur. Steuerung der
angeschlossenen Browser. Verteilung der Tests und
Einsammeln der ...
describe('simple controller', function() {

var $rootScope, $scope, createController;



beforeEach(module('simpleCtrl'));...
End2End
End2End
Werden mit Protractor erstellt. Bauen auf Selenium
WebDriver auf. Testen die komplette Applikation inklusive
Serve...
End2End
describe('project list', function() {

it('should check the first item in the list', function(done) {

browser.get...
Test Doubles
Regina Kaute / pixelio.de
Test Doubles
Test Doubles für Services verwenden, z.B. $httpBackend.
Für alles Übrige kommt Sinon.js zum Einsatz.
Module Loader
Bernd Kasper / pixelio.de
Module Loader
Keine Script-Tags mehr schreiben. Abhängigkeiten zwischen
Dateien werden aufgelöst. Können im Build zu einer...
Module Loader
define(['angular'], function(angular) {

var controller = angular.module('controller', [])

.controller('Lis...
Statische
Codeanalyse
Tim Reckmann / pixelio.de
Statische Codeanalyse
Statische Prüfung des Quellcodes. Auffinden von
Antipatterns oder Betrachtung bestimmter Metriken wie...
Statische Codeanalyse
Buildsysteme
schau media / pixelio.de
Buildsysteme
Automatisieren von wiederkehrenden Aufgaben wie Tests,
Build, Linting
Beispiele:
- grunt
- gulp
- npm
Buildsysteme
module.exports = function(grunt) {

grunt.initConfig({

copy: {...},

clean: {

bower: ['bower_components']

...
Kommunikation
Aka / pixelio.de
Kommunikation
Wie werden Daten zwischen einzelnen Komponenten einer
Applikation ausgetauscht?
Kommunikation
innerhalb der Applikation
Services
Services sind Singletons und können an verschiedenen
Stellen verwendet werden.
Mit Services lassen sich Nachricht...
angular.module('myApp', [])

.factory('MsgBus', MsgBus);



function MsgBus() {

var callbacks = {};



return {

on: on,
...
Direktiven
Direktiven sind Marker im HTML, die den Funktionsumfang
von HTML erweitern.
Mithilfe der Scope-Eigenschaft der ...
Direktiven
<my-directive name="{{ name }}" color="color" reverse="reverseName()">
angular.module('app', [])

.directive('m...
Kommunikation zum
Server
Kommunikation zum Server
Services, die die Kommunikation kapseln.
$http, restangular, ngResource, angular-websocket
Abstra...
Kommunikation zum Server
$http.get('/weather').success(function (data) {

data.forEach(function (item) {

if (item.id === ...
Performance
Thomas Siepmann / pixelio.de
Performance
Angular ist ein Framework, das bedeutet Overhead.
Two Way Data-Binding mit Dirty Checking ist eines der
größte...
Performance
Performance
Bei tiefergehenden Performance-Problemen: Developer Tools
nutzen und die Applikation auseinander nehmen.
Fragen?
Rainer Sturm / pixelio.de
KONTAKT
Sebastian Springer
sebastian.springer@mayflower.de
Mayflower GmbH
Mannhardtstr. 6
80538 München
Deutschland
@basti...
Große Applikationen mit AngularJS
Große Applikationen mit AngularJS
Nächste SlideShare
Wird geladen in …5
×

Große Applikationen mit AngularJS

2.046 Aufrufe

Veröffentlicht am

Eine Sammlung von Best Practices für Applikationen mit AngularJS. Der Vortrag stellt Strukturen und Konventionen vor, mit denen sich auch umfangreiche Applikationen wartbar und erweiterbar halten lassen.

Veröffentlicht in: Software
0 Kommentare
4 Gefällt mir
Statistik
Notizen
  • Als Erste(r) kommentieren

Keine Downloads
Aufrufe
Aufrufe insgesamt
2.046
Auf SlideShare
0
Aus Einbettungen
0
Anzahl an Einbettungen
124
Aktionen
Geteilt
0
Downloads
22
Kommentare
0
Gefällt mir
4
Einbettungen 0
Keine Einbettungen

Keine Notizen für die Folie

Große Applikationen mit AngularJS

  1. 1. Große Applikationen mit
  2. 2. WHO AM I? • Sebastian Springer • aus München • arbeite bei Mayflower • https://github.com/sspringer82 • @basti_springer • Consultant,Trainer,Autor
  3. 3. Konventionen Wenn ihr heute nur einen Punkt mitnehmt, dann: Haltet euren Code und eure Struktur einheitlich.
  4. 4. Was ist eine große Applikation? K. Bangwa / pixelio.de
  5. 5. Großer Funktionsumfang
  6. 6. Grundsätzliches Bernd Kasper / pixelio.de
  7. 7. Sprechender Code
  8. 8. Sprechender Code angular.module('myApp', [])
 .controller('MyCtrl', MyCtrl);
 
 
 function MyCtrl() {
 var vm = this;
 
 vm.onSaveButtonClicked = onSaveButtonClicked;
 
 function onSaveButtonClicked() {}
 }
  9. 9. Sprechender Code Was ist, wenn ein Funktionsname zu lange wird? Dann macht die Funktion wahrscheinlich zu viel und sollte aufgeteilt werden.
  10. 10. Komplexität Tim Reckmann / pixelio.de
  11. 11. Komplexität Applikation in kleinere, weniger komplexe Einheiten unter- teilen und diese zu einem Komplettsystem integrieren.
  12. 12. Komplexität vm.start = function() {
 vm.status = "started";
 
 stopInterval = $interval(function () {
 
 var data = readerDataFactory.getPart();
 if (data) {
 vm.part = data;
 } else {
 vm.part = "";
 vm.status = "stopped";
 $interval.cancel(stopInterval);
 stopInterval = null;
 vm.text = readerDataFactory.getText();
 }
 }, 1000 * 60 / readerDataFactory.getWPM());
 }; vm.stop = function() {
 vm.status = "stopped";
 $interval.cancel(stopInterval);
 stopInterval = null;
 };
  13. 13. Styleguide
  14. 14. Styleguide Der Quellcode soll überall gleich aussehen. Dem Quellcode soll man nicht ansehen, wann er von wem mit welcher Laune geschrieben wurde. Ein guter Start ist: https://github.com/johnpapa/angular- styleguide
  15. 15. Werkzeuge Gila Hanssen / pixelio.de
  16. 16. Entwicklungsumgebung
  17. 17. Entwicklungsumgebung Autocompletion: Variablen und Konstrukte vervollständigen. Hilfestellung bieten. Highlighting: Visuelle Abgrenzung zwischen verschiedenen Konstrukten für erhöhte Lesbarkeit. Linting: Anti-Pattern-Erkennung, um Fehler zu vermeiden. Angular Plugins für WebStorm, Eclipse,…
  18. 18. Entwicklungsumgebung
  19. 19. Paketverwaltung Rainer Sturm / pixelio.de
  20. 20. Paketverwaltung Installation externer Bibliotheken. Versionsverwaltung und Überblick über installierte Bibliotheken. Auflösung von Abhängigkeiten. Paketmanager: bower, npm, spmjs,…
  21. 21. Paketverwaltung $ bower install angular bower angular#* cached git://github.com/angular/bower-a bower angular#* validate 1.4.0 against git://github.com/a bower angular#~1.4.0 install angular#1.4.0 angular#1.4.0 bower_components/angular
  22. 22. Yeoman Scaffolding für Webprojekte. Bietet Generatoren, um schnell häufig benötigte Strukturen im Projekt zu schaffen.
  23. 23. Yeoman npm install -g yo npm install -g generator-angular yo angular myApp yo angular:controller account
  24. 24. Yeoman Problem: Aber unsere Applikation ist etwas ganz besonderes und die bestehenden Generatoren passen für uns nicht. Wir müssen jede Struktur nochmal anfassen und umbauen. Lösung: Eigene Generatoren erstellen. Guide: http://yeoman.io/authoring/
  25. 25. Struktur Initiative Echte Soziale Marktwirtschaft IESM / pixelio.de
  26. 26. Struktur Wie baut man eine Applikation auf, damit sie wartbar und erweiterbar bleibt? Wo findet man bestimmte Komponenten? Wie werden die Verzeichnisse strukturiert? Wie heißen die Dateien?
  27. 27. Ein Verzeichnis pro Feature
  28. 28. Ein Verzeichnis pro Feature Features unabhängig halten. Wiederverwendbarkeit in anderen Applikationen erreichen. Klares Namespacing einführen.
  29. 29. Ein Verzeichnis für shared content
  30. 30. Ein Verzeichnis für shared content Gemeinsam genutzte Komponenten liegen in einer eigenen Hierarchie. Abhängigkeiten zwischen Modulen werden vermieden.
  31. 31. Eine Komponente pro Datei
  32. 32. Eine Komponente pro Datei Controller, Services, Direktiven, … erhalten jeweils ihre eigene Datei. Single Responsibility - eine Datei ist nur für einen Zweck da. Zuordnung von Zuständigkeiten ist einfach. Das Auffinden von Quellcode ist schneller.
  33. 33. Eine Komponente pro Datei angular.module('user.controller.login', [])
 .controller('user.loginController', LoginController);
 
 function LoginController() {
 
 }
  34. 34. Einheitliche sprechende Benennung
  35. 35. Einheitliche sprechende Benennung Die Namen von Dateien und deren Speicherort folgt einem konsistenten Schema. Das Lokalisieren von Komponenten wird einfacher. /user/login.controller.js
  36. 36. Konfiguration auslagern
  37. 37. Konfiguration auslagern Die Konfiguration eines Moduls liegt in einer eigenen Datei innerhalb des Moduls. Die Konfiguration erfolgt an einer zentralen Stelle und nicht über die Komponenten verteilt.
  38. 38. Konfiguration auslagern angular.module('addressBook.translation', ['pascalprecht.translate'])
 .config(['$translateProvider', function ($translateProvider) {
 $translateProvider.translations('de', de);
 $translateProvider.translations('en', en);
 $translateProvider.preferredLanguage('en');
 }]);
  39. 39. Struktur flach halten
  40. 40. Struktur flach halten Die Verzeichnisstruktur sollte initial möglichst flach sein. Bei Bedarf (viele Dateien pro Verzeichnis) tiefer werden.
  41. 41. Routing Erich Westendarp / pixelio.de
  42. 42. Routing Navigation zwischen verschiedenen States in der Applikation. States arbeiten mit Views, die benannt sein können. Optional können Controller hinzugefügt werden. Implementierungen: - ngRoute - angular-ui-router
  43. 43. Routing - Konfiguration angular.module('adress', ['ui.router'])
 .config(ConfigFn);
 
 ConfigFn.$inject = ['$stateProvider', '$urlRouterProvider'];
 
 function ConfigFn ($stateProvider, $urlRouterProvider) {
 $urlRouterProvider.otherwise('/list');
 
 $stateProvider.state('list', {
 url: '/list',
 template: tplList,
 controller: 'listCtrl'
 });
 }
  44. 44. Routing - advanced Mehrere benannte Views <body>
 <div ui-view="content"></div>
 <div ui-view="info"></div>
 </body> $stateProvider.state('list', {
 url: '/list',
 views: {
 content: {
 template: tplListContent,
 controller: 'listContentCtrl'
 },
 info: {
 template: tplListInfo,
 controller: 'listInfoCtrl'
 }
 }

  45. 45. Routing - advanced <div ui-view></div>
 <a ui-sref="state1">State 1</a> <a ui-sref="state1.list">Show List</a>
 <div ui-view></div> index.html state1.html state1.list.html <ul>
 <li ng-repeat="item in items">{{ item }}</li>
 </ul> Nested Views
  46. 46. Routing - advanced Nested Views $stateProvider
 .state('state1', {
 url: "/state1",
 templateUrl: "partials/state1.html"
 })
 .state('state1.list', {
 url: "/list",
 templateUrl: "partials/state1.list.html",
 controller: function($scope) {
 $scope.items = ["A", "List", "Of", "Items"];
 }
 });
  47. 47. Routing - new Router Redesignter Router. Folgeversion von ngRoute. Aktuell noch nicht stabil. Ist aber für 1.4 und 2 vorgesehen.
  48. 48. DRY Don’t Repeat Yourself
  49. 49. DRY Sobald eine Routine zum zweiten Mal implementiert wird, sollte sie in einen eigenständigen Service ausgelagert werden. Diese Services können abstrahiert und durch unterschiedliche Konfiguration an mehreren Stellen wiederverwendet werden.
  50. 50. DRY Nützliche Helper können in einer eigenen Library gesammelt werden. z.B. Logger
  51. 51. NIH Not Invented Here
  52. 52. NIH Bevor man etwas selbst implementiert, sollte man zuerst prüfen, ob es für diese Problemstellung nicht schon eine Lösung gibt. Beispiele: - REST-Kommunikation: ngResource, restangular - Websocket: angular-websocket, ng-websocket - localstorage: angular-local-storage - Routing: ngRoute, ui-router - Translation: ngTranslate
  53. 53. Dokumentation René Golembewski / pixelio.de
  54. 54. Dokumentation Es muss nicht jede Funktion dokumentiert werden (z.B. Callbacks) Lieber sprechenden Code schreiben.
  55. 55. Dokumentation Schnittstellen zwischen Teams/Projekten müssen dokumentiert und AKTUELL gehalten werden.
  56. 56. Dokumentation Angular selbst verwendet jsdoc bzw. ngdoc und Dgeni zum Parsen. Weitere Infos: https://github.com/angular/angular.js/wiki/Writing-AngularJS- Documentation
  57. 57. Dokumentation /**
 * @name trim
 * @private
 *
 * @description
 * trim polyfill
 *
 * @returns {string} The string stripped of whitespace from both ends
 */
 var trim = function() {
 return this.toString().replace(/^s+|s+$/g, '');
 };
  58. 58. Typescript Zur Dokumentation von Schnittstellen kann zusätzlich Typescript eingesetzt werden. Möglichkeit zur Beschreibung von Signaturen, Klassen und Interfaces.
  59. 59. Code Corinna Dumat / pixelio.de
  60. 60. Struktur vs. Implementierung
  61. 61. Struktur vs. Implementierung Trennung der konkreten Implementierung und der Struktur. Rückgabe/Bindables getrennt von den Funktionsdefinitionen.
  62. 62. Struktur vs. Implementierung function ListCtrl() {
 var vm = this;
 
 vm.onEdit = onEdit;
 vm.onDelete = onDelete;
 
 function onEdit(id) {…}
 
 function onDelete(id) {…} 
 } function ItemService() {
 return {
 fetch: fetch,
 save: save
 };
 
 function fetch() {...}
 function save() {...}
 } Controller: Factory:
  63. 63. init-Funktion
  64. 64. init-Funktion Sämtliche Logik, die in einem Controller zur Initialisierung direkt ausgeführt wird, wird in einer Funktion gekapselt. So sieht man auf einen Blick, was passiert, wenn dieser Controller erstellt wird.
  65. 65. init-Funktion function ListCtrl(itemStore) {
 var vm = this;
 
 vm.items = [];
 
 function init() {
 itemStore.fetch().then(function(items) {
 vm.items = items;
 });
 }
 
 init();
 }
  66. 66. Logik in Services
  67. 67. Logik in Services Controller sollten nicht zu viel Logik beinhalten, da sie dadurch unleserlich werden. Umfangreichere Logik in Services auslagern.
  68. 68. Ein Controller pro View
  69. 69. Ein Controller pro View Mehrere Views sollten sich nicht einen Controller teilen. Dies macht es meistens erforderlich, Logikweichen einzubauen, die die Lesbarkeit beeinträchtigen.
  70. 70. Promises JMG / pixelio.de
  71. 71. Promises Promises sind ein Mittel, um asynchronen Programmfluss zu steuern. Sie erhöhen die Lesbarkeit des Quellcodes und helfen bei der Fehlerbehandlung.
  72. 72. Promises ListCtrl.$inject = ['$q', '$timeout'];
 
 function ListCtrl($q, $timeout) {
 
 function async() {
 return $q(function (resolve, reject) {
 $timeout(function () {
 resolve('Hello');
 }, 1000);
 });
 }
 
 async().then(function (data) {
 vm.data = data;
 });
 }
  73. 73. Testing? Rike / pixelio.de
  74. 74. Tests Mindestens zwei Ebenen von Tests: Unittests und End2End- Tests. Manuelle Tests können allerdings nicht entfallen, da immer noch irgendwo Logikfehler versteckt sein können.
  75. 75. Unittests
  76. 76. Unittests Karma: bietet die Infrastruktur. Steuerung der angeschlossenen Browser. Verteilung der Tests und Einsammeln der Daten. Jasmine: Formulieren der Tests. Die Tests liegen bei den Dateien, die sie testen sollen. Tests werden schneller gefunden und besser gepflegt, sind gegenwärtiger.
  77. 77. describe('simple controller', function() {
 var $rootScope, $scope, createController;
 
 beforeEach(module('simpleCtrl'));
 
 beforeEach(inject(function($injector) {
 $rootScope = $injector.get('$rootScope');
 $scope = $rootScope.$new();
 var $controller = $injector.get('$controller');
 createController = function() {
 return $controller('PasswordCtrl', {
 '$scope': $scope
 });
 };
 }));
 
 it('should have a name property with a value', function() {
 var controller = createController();
 expect($scope.name).toBe('Hans-Peter');
 });
 
 it('should execute a function', function() {
 var controller = createController();
 expect($scope.myFunc()).toBe('hello');
 })
 });
  78. 78. End2End
  79. 79. End2End Werden mit Protractor erstellt. Bauen auf Selenium WebDriver auf. Testen die komplette Applikation inklusive Server. Längere Laufzeit als Unittests. Testen Integration einzelner Komponenten in die Applikation. Werden in einer parallelen Verzeichnishierarchie gepflegt.
  80. 80. End2End describe('project list', function() {
 it('should check the first item in the list', function(done) {
 browser.get('/');
 
 var name = element(by.repeater('project in projects')
 .row(0)
 .column('name'));
 
 expect(name.getText()).toEqual('Projekt A');
 
 done();
 });
 });
  81. 81. Test Doubles Regina Kaute / pixelio.de
  82. 82. Test Doubles Test Doubles für Services verwenden, z.B. $httpBackend. Für alles Übrige kommt Sinon.js zum Einsatz.
  83. 83. Module Loader Bernd Kasper / pixelio.de
  84. 84. Module Loader Keine Script-Tags mehr schreiben. Abhängigkeiten zwischen Dateien werden aufgelöst. Können im Build zu einer Datei zusammengefasst werden. Beispiele: - require.js - Browserify - SystemJS - …
  85. 85. Module Loader define(['angular'], function(angular) {
 var controller = angular.module('controller', [])
 .controller('ListCtrl', ListCtrl);
 
 function ListCtrl() {…}
 
 return controller;
 });
  86. 86. Statische Codeanalyse Tim Reckmann / pixelio.de
  87. 87. Statische Codeanalyse Statische Prüfung des Quellcodes. Auffinden von Antipatterns oder Betrachtung bestimmter Metriken wie z.B. Komplexität. Tools: - linter (jslint, jshint, eslint) - Plato
  88. 88. Statische Codeanalyse
  89. 89. Buildsysteme schau media / pixelio.de
  90. 90. Buildsysteme Automatisieren von wiederkehrenden Aufgaben wie Tests, Build, Linting Beispiele: - grunt - gulp - npm
  91. 91. Buildsysteme module.exports = function(grunt) {
 grunt.initConfig({
 copy: {...},
 clean: {
 bower: ['bower_components']
 },
 shell: {
 bower: {
 command: 'bower install'
 }
 },
 watch: {
 scripts: {
 files: ['src/**/*.js', 'src/**/*.html'],
 tasks: ['copy:app']
 }
 },
 requirejs: {...}
 });
 require('load-grunt-tasks')(grunt);
 grunt.registerTask('bower', ['shell:bower', 'copy:bower', 'clean:bower']);
 };
  92. 92. Kommunikation Aka / pixelio.de
  93. 93. Kommunikation Wie werden Daten zwischen einzelnen Komponenten einer Applikation ausgetauscht?
  94. 94. Kommunikation innerhalb der Applikation
  95. 95. Services Services sind Singletons und können an verschiedenen Stellen verwendet werden. Mit Services lassen sich Nachrichtenbusse umsetzen, die zur Kommunikation zwischen den Komponenten verwendet werden können.
  96. 96. angular.module('myApp', [])
 .factory('MsgBus', MsgBus);
 
 function MsgBus() {
 var callbacks = {};
 
 return {
 on: on,
 trigger: trigger
 };
 
 function on(event, callback) {
 if (callbacks[event]) {
 callbacks[event] = [callback];
 return this;
 }
 callbacks[event].push(callback);
 }
 function trigger(event, data) {
 if (callbacks[event]) {
 callbacks[event].forEach(function (callback) {
 callback(data);
 });
 }
 }
 }
  97. 97. Direktiven Direktiven sind Marker im HTML, die den Funktionsumfang von HTML erweitern. Mithilfe der Scope-Eigenschaft der Direktive kann zwischen dem außenliegenden Controller und der Direktive kommuniziert werden.
  98. 98. Direktiven <my-directive name="{{ name }}" color="color" reverse="reverseName()"> angular.module('app', [])
 .directive('myDirective', myDirective);
 
 function myDirective() {
 return {
 scope: {
 name: '@', // one way (read only)
 color: '=', // two way
 reverse: '&' // function binding
 }
 }
 }
  99. 99. Kommunikation zum Server
  100. 100. Kommunikation zum Server Services, die die Kommunikation kapseln. $http, restangular, ngResource, angular-websocket Abstrahieren die Schnittstelle zum Server. Können zum Testen durch Stubs ersetzt werden.
  101. 101. Kommunikation zum Server $http.get('/weather').success(function (data) {
 data.forEach(function (item) {
 if (item.id === id) {
 vm.data = item;
 }
 });
 });
  102. 102. Performance Thomas Siepmann / pixelio.de
  103. 103. Performance Angular ist ein Framework, das bedeutet Overhead. Two Way Data-Binding mit Dirty Checking ist eines der größten Performance-Probleme. Mögliche Lösung: angular-vs-repeat, ngGrid
  104. 104. Performance
  105. 105. Performance Bei tiefergehenden Performance-Problemen: Developer Tools nutzen und die Applikation auseinander nehmen.
  106. 106. Fragen? Rainer Sturm / pixelio.de
  107. 107. KONTAKT Sebastian Springer sebastian.springer@mayflower.de Mayflower GmbH Mannhardtstr. 6 80538 München Deutschland @basti_springer https://github.com/sspringer82

×