Top Banner
AngularJS SOGETI ANGULARJS TRAINING DAG 3 - ADVANCED ANGULAR
42

AngularJS - · PDF fileSUMMARY Modules Dependency Injection Unit testing Views & directives Controllers & scope Filters Services

Feb 06, 2018

Download

Documents

buianh
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views & directives Controllers & scope Filters Services

AngularJS

SOGETI ANGULARJS TRAININGDAG 3 - ADVANCED ANGULAR

Page 2: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views & directives Controllers & scope Filters Services

THE PRESENTATIONsogeti-summerschool.herokuapp.com/day/3

sogeti-summerschool.herokuapp.com/day/3?print-pdf

Page 3: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views & directives Controllers & scope Filters Services

SUMMARYModulesDependency InjectionUnit testingViews & directivesControllers & scopeFiltersServices

Page 4: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views & directives Controllers & scope Filters Services

TODAYS AGENDACustom directivesPromisesToolingLearning resources

Page 5: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views & directives Controllers & scope Filters Services

CUSTOM DIRECTIVESAngular directives: ng-repeat, ng-if, ng-init, etc.

Page 6: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views & directives Controllers & scope Filters Services

PROBLEM<div ng­controller="ProductListController as productsCtrl"> <h2>Products</h2>

<p>Showing productsCtrl.products.length of productsCtrl.total products</p>

<div class="product­container"> <div class="product" ng­repeat="product in productsCtrl.products"> <h5>product.title</h5> <em>Price: product.price | currency</em> <img ng­src="product.imageLink"> <span>Stock: product.stock</span> <ul> <li ng­repeat="feature in product.features"> feature.title: <strong>feature.value</strong> </li> </ul> </div> </div> <p>Page: productsCtrl.page <a href="#/page/productsCtrl.page ­ 1">&lt;</a> <a href="#/page/productsCtrl.page + 1">&gt;</a> </p></div>

Page 7: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

SOLUTION<div ng­controller="ProductPageController as productPageCtrl"> <h2>Products</h2>

<p>Showing productPageCtrl.products.length of productPageCtrl.total products</p>

<div class="product­container"> <product ng­repeat="product in productPageCtrl.products"></product> </div>

<pagination page="productPageCtrl.page"></pagination></div>

Page 8: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

SOLUTION<div class="product"> <h5>product.title</h5> <em>Price: product.price | currency</em> <img ng­src="product.imageLink"> <span>Stock: product.stock</span> <ul> <li ng­repeat="feature in product.features"> feature.title: <strong>feature.value</strong> </li> </ul></div>

Page 9: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

SOLUTIONapp.directive('product', function () return templateUrl: 'product.template.html' // Or use 'template' with the contents directly ;)

Page 10: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

LET'S GET TO IT!Documentation

http://jsbin.sgtifrontend.nl/wago/edit?html,js,output

1. See the list of properties? Try and make a 'property'directive:

<li property ng­repeat="...."></li>

Page 11: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

DIRECTIVE DEFINITION OBJECTtemplate or templateUrlrestrictscopecontrollerreplacecompilelink

Page 12: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

SCOPING<div ng­controller="SomeController"> <span>Controller</span> <input ng­model="title"> title <span>Directive</span> <some­directive></some­directive></div>

app.controller('SomeController', function ($scope) $scope.title = 'test';).directive('someDirective', function () return template: '<input ng­model="title"> title' ;);

Controller (parent) test test

Directive (child) test test

Page 13: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

SCOPINGapp.controller('SomeController', function ($scope) $scope.title = 'test';).directive('someDirective', function () return template: '<input ng­model="title"> title', scope: false ;);

<some­directive></some­directive>

Controller (parent) test test

Directive (child) test test

Page 14: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

SCOPINGapp.controller('SomeController', function ($scope) $scope.title = 'test';).directive('someDirective', function () return template: '<input ng­model="title"> title', scope: true ;);

<some­directive></some­directive>

Controller (parent) test test

Directive (child) test test

Page 15: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

SCOPINGapp.controller('SomeController', function ($scope) $scope.title = 'test';).directive('someDirective', function () return template: '<input ng­model="title"> title', scope: title: '@myTitle' ;);

<some­directive my­title="title"></some­directive>

Controller (parent) test test

Directive (child) test test

Page 16: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

SCOPINGapp.controller('SomeController', function ($scope) $scope.title = 'test';).directive('someDirective', function () return template: '<input ng­model="title"> title', scope: title: '=myTitle' ;);

<some­directive my­title="title"></some­directive>

Controller (parent) test test

Directive (child) test test

Page 17: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

SCOPE (ISOLATED SCOPE)@ - Bind local scope to DOM attribute value

<my­directive my­attr="hello name"></my­directive>

scope: localModel: '@myAttr'

= - Bi-directional binding to parent scope<my­directive my­attr="parentModel"></my­directive>

scope: localModel: '=myAttr'

Page 18: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

LET'S GET TO IT!Documentation

http://jsbin.sgtifrontend.nl/hewi/edit?html,js,output

1. Note the way how we call the directives from theHTML

2. Note the way how the scope variables are boundwithin the directive

3. To reset: press the "Run with JS" button in the top rightcorner of the output

Page 19: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

TESTING DIRECTIVESapp.directive('sumHeader', function () return template: '<h1>1 + 1</h1>' ;);

describe('Unit testing directive', function () var $compile, $rootScope; beforeEach(module('myApp'));

beforeEach(inject(function (_$compile_, _$rootScope_) $compile = _$compile_; $rootScope = _$rootScope_; ));

it('Compiles correctly', function () var element = $compile("<sum­header></sum­header>")($rootScope); $rootScope.$digest(); expect(element.html()).toContain("2"); ););

Page 20: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

ASYNCHRONOUS JAVASCRIPTNetworking operationsScheduled functionsOften using callbacks

Page 21: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

CALLBACK// An example of a lengthy task (like a heavy HTTP request),// emulated using window.setTimeout()function slowTask(callback) setTimeout(callback, 3000);// This will obviously be printed firstconsole.log('Starting slow task...');

// Here we execute the lengthy taskslowTask( // This function will only be called once the task is done function () // This will print last console.log('Task done!'); );

// This will print immediately after the first console.log()console.log('Task running...');

Start slow function

TASK NOT STARTED YET...

Page 22: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

PROBLEMfunction organizeParty() getWeatherForecast('tomorrow', function (error, forecast) if (error) console.error('Error: ' + error); if(forecast === 'good') planParty('tomorrow', function (error, plans) if (error) console.error('Error: ' + error); else getFriendsList(function (error, friends) if (error) console.error('Error: ' + error); else invite(friends, function (error, plans) // etc, etc, etc.... ); ); ); );

Page 23: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

SOLUTION: PROMISESA promise to complete a taskEasy access to task statusFlatten nested callbacks

Page 24: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

A PROMISEContains:

Status (pending, fulfilled, rejected)Function referenceCallback references for:

then (fulfilled)catch (rejected)finally (always)

Page 25: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

PROMISESvar promise = $q( // Promise function reference function (resolve, reject) // AngularJS alternative for window.setTimeout() $timeout( // Delayed callback function function () // Either 1 or 0 var result = Math.round(Math.random()); if (result === 1) // Fulfill the promise resolve(); else // Reject the promise reject(); , 3000 ); );

promise.then(function () console.log('Done!'););

Page 26: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

CHAININGthen, catch, and finally return promises

somePromise .then(onComplete) .then(afterOnComplete) .catch(onReject) .finally(cleanUp);

Return values are forwardedgetWeatherForecast() .then(function (forecast) console.log('Forecast is: ' + forecast); return forecast.temperature; ) .then(function (temperature) console.log('Temperature is: ' + temperature); ) .catch(function (error) console.error('Error occurred: ' + error); );

Page 27: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

SHORTHANDSCreating a promise that will always be resolved with a

valuevar promise = $q.when(value);

Creating a promise that will always be rejected with avalue

var promise = $q.reject(value);

Page 28: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

PLANNING A PARTYfunction organizeParty() return getWeatherForecast('tomorrow') .then(function (forecast) if (forecast === 'good') return 'tomorrow'; return $q.reject('Bad weather'); ) .then(planParty) .then(getFriendsList) .then(invite) .catch(function (error) console.error(error); return $q.reject(error); );

Page 29: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

NOW LET'S TRY IT!http://jsbin.sgtifrontend.nl/zive/edit?html,js,output

1. Add another date value, yesterday, and change theweather forecast function to return an error (rejectedpromise) when yesterday is selected

2. Add more 'slow' functions (use previous partyplanning examples)

3. Add more 'then' steps to planParty() function4. Make sure your error flow is still working properly

Page 30: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

PRACTICAL CASEA data service, connecting to a RESTful API

function DataService($http, $q) this.getData = function getData() return $http.get('/some/api/endpoint') .then(function (response) return response.data; ) .catch(function (response) return $q.reject(response.data); ); ;

DataService.$inject = ['$http', '$q'];angular.module('app', []) .service('DataService', DataService);

Page 31: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

PRACTICAL CASEGetting the data in a controller

function DataController(DataService) var vm = this;

DataService.getData() .then(function (data) vm.data = data; ) .catch(function (error) vm.error = error; );

DataController.$inject = ['DataService'];angular.module('app') .controller('DataController', DataController);

Page 32: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

PRACTICAL CASETesting your data service

describe('DataService', function () var $httpBackend, DataService;

beforeEach(module('testModule')); beforeEach(inject(function (_$httpBackend_, _DataService_) $httpBackend = _$httpBackend_; DataService = _DataService_; ));

it('should retrieve data', function () successFn = jasmine.createSpy('successFn'); failureFn = jasmine.createSpy('failureFn');

$httpBackend.expectGET('/some/api/endpoint').respond(200, ); DataService.getData().then(successFn).catch(failureFn); $httpBackend.flush();

expect(successFn).toHaveBeenCalledWith(); expect(failureFn).not.toHaveBeenCalled(); ););

Page 33: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

TESTING DATA SERVICES$http documentation

$httpBackend documentation

http://jsbin.sgtifrontend.nl/joh/edit?js,output

1. Add another async function to the service, sendDatawhich will do a POST request

2. Test the new sendData function3. Extra:

3.1 Test the error flow of both async functions (youcan return error HTTP status codes)

Page 34: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

TOOLINGIDEBuild pipeline: task runners

GruntGulp

Plugins

Page 35: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

TASK RUNNERSCode quality checkingConcatenationMinificationAutomated testing

Optimize your project for production!

Page 36: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

CODE QUALITYJSHintESLintJSCS

Page 37: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

AUTOMATED TESTINGUnit testing

Test runner: KarmaRun in watch modePhantomJS: the headless browser

Page 38: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

AUTOMATED TESTINGEnd-to-end (E2E) testing

Real in-browser testsTest runner: ProtractorSelenium

Page 39: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

POPULAR PLUGINSRouting libraries

ngRoute (angular-route)AngularUI Router (ui-router)

Animation / UX librariesngAnimate (angular-animate)AngularUI BootstrapngMaterial (angular-material)

API librariesngResource (angular-resource)RESTAngular

Page 41: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

SUMMARYCustom directivesPromisesToolingLearning resources

Page 42: AngularJS -   · PDF fileSUMMARY Modules Dependency Injection Unit testing Views &amp; directives Controllers &amp; scope Filters Services

ENJOY ANGULARJS!