angularjs und typ-d'oh!3
TRANSCRIPT
ANGULARJS UND TYP-D'OH!3Christian Herberger
ÜBER MICHIntegratorPHP-EntwicklerFE-Entwickler
PUNKT.DETYPO3-Komplettpakete in Karlsruhe25 Mitarbeiter
DER ROTE FADENWas ist AngularJS (und was kann es)? (Live und in Farbe!)Wie kann man AngularJS mit TYPO3 nutzen?StolpersteineAusblick
ANGULARJS¡Ay, caramba!
WAS IST ANGULARJS?HTML enhanced for web apps
MVC/MVVMTwoWay/Bidirectional Data BindingDependency InjectionDirektiven als Erweiterung von HTMLTestbarkeit von Grund auf
Die Drei D
MVC/MVVM
MVC
MVVM
BEISPIEL... kommt gleich
TWOWAY/BIDIRECTIONAL DATA BINDING
<script type="text/javascript" src="Resources/JavaScript/angular.js"></script><div ng-app> <input type="text" ng-model="name" placeholder="Bitte Namen eingeben"/><br /> <p>Hallo, ich bin {{name}}</p></div>
Bitte Namen eingeben
Hallo, ich bin
A BIT MORE...
<script type="text/javascript" src="Resources/JavaScript/angular.js"></script><script type="text/javascript"> angular.module('displayNameApp', []);
angular.module('displayNameApp').controller('displayNameController', function($scope) $scope.name = 'Apu Nahasapemapetilon'; $scope.resetName = function() { $scope.name = 'Apu Nahasapemapetilon'; }; });</script><div ng-app="displayNameApp"> <div ng-controller="displayNameController"> <input type="text" ng-model="name" placeholder="Bitte Namen eingeben"/><br /> <p>Hallo, ich bin {{name}}</p> <input type="button" ng-click="resetName()"> </div></div>
Apu Nahasapemapetilon
Hallo, ich bin Apu Nahasapemapetilon
Reset Name
WEITERE MÖGLICHKEITENng-repeat für Ausgabe von Arraysselect mit ng-optionsng-init als KonstruktorVerschachtelte Controller mit Vererbung
DEPENDENCY INJECTION
WAS IST DI?Benötigt ein Objekt ein anderes Objekt als Abhängingkeit, zieht es
ein zentral abgelegtes Objekt ab und muss es nicht selbsterstellen
Fuktioniert bei allen "Factories" (Modulen, Controllern,Direktiven, Services, ...)
BEISPIEL
<script type="text/javascript"> angular.module('displayNameApp', ['fremdModul']);
angular.module('displayNameApp').controller('displayNameController', function($scope, $http, eigenerService) { $scope.name = 'Apu Nahasapemapetilon'; $scope.resetName = function() { $scope.name = $http.get(...); var blubb = eigenerService.doSomething(); }; });
angular.module('displayNameApp').factory('eigenerService', function($http) { return { doSomething = function() {...}; }; });</script>
DI VERÄNDERNAngular bietet einen injector mit Funktionen wie get()Abhängig von Conditions, oder jedem eingenen Code, andereDependencies einspielen
BEISPIEL
<script type="text/javascript"> angular.module('displayNameApp', []); angular.module('displayNameApp').controller('displayNameController', function($scope, $http) {
if ($scope.testMode) { $http = angular.injector.get('myHttpMock'); }
$scope.name = 'Apu Nahasapemapetilon'; $scope.resetName = function() { $scope.name = $http.get(...); }; });</script>
DIREKTIVEN ALS ERWEITERUNG VON HTML
WÄR DAS NICHT GENIAL?
<name-list last-name="Simpson"></name-list>
OUTPUT:Homer SimpsonMarge SimpsonBart SimpsonLisa SimpsonMaggie Simpson
ES IST SO GENIAL!
DAS "NORMALE" JAVASCRIPT
<script type="text/javascript"> angular.module('displayNameApp', []);
angular.module('displayNameApp').directive('nameList', function($http) { return { scope: { lastName: '@lastName' }, restrict: 'E', templateUrl: 'nameList.html', link: function(scope) { $http.get(/* ajax call with last name */) .success(function(resonseData) { scope.nameList = responseData.nameList; }); } } });</script>
DAS "TEMPLATE"
<div> <script type="text/ng-template" id="nameList.html"> <div> <ul> <li ng-repeat="name in nameList">{{name}} {{lastName}}</li> </ul> </div> </script> <name-list last-name="Simpson"></name-list></div>
BEISPIEL... gibt's hier keins - nicht relevant für unsere Anwendung
TESTBARKEIT
UNIT TESTSGute Integration in aktuelle Testframeworks (Karma, Jasmine)Durch DI einfach Code-Einheiten zu isolierenJeder Service, Controller, ... kann einzeln losgelöst aufgerufenwerdenIn der Doku gibt es Test-Doku für jede Variante
"END TO END"-TESTungefähr wie Oberflächentest - Aufruf der Funktion, Vergleichdes Outputs mit definierten Mocksangular-mock als Modul für fertige MocksIntegration von HTML-Template-Tools in Karma/JasmineJS-Tests laufen auf Browsern -> Reale Bedingungen
INTEGRATION IN TYPO3
IDEENEine Action für die App (=> SinglePage App)Action komplett Cachebar machenModels mit $exposedProperties und getExposedProperties()anreichernObjectToJson-Parser nutzen, JSON an ng-init-AufrufeübergebenFluid nutzen!Angular-Templates als Partials -> Ordnung, Fluid ;)Kommunikation mit TYPO3 über AJAX und eIDZugriffsrechte auf die Seite und das Plugin mit der App
STOLPERSTEINE
STOLPERSTEINEFluid + JSON = 'Array' -> <![CDATA[ nutzen!array('name' => 'value') wird in JSON ein Objekt und damitnicht sortierbarJavaScript ist eine asnychron arbeitende SpracheAnderes JavaScript kann die App stören, Ladezeit verlängernusw. -> Möglichst losgelöst einbinden
AUSBLICK
Fragen? Antworten! Diskussion?
Vielen Dank für die Aufmerksamkeit!