AngularJS
AngularJSoverview • AngularJS is a JavaScript MVW framework made by Google for building complex client-side applications. • It provides everything for development of SPA out of the box
AngularJScorefeatures • Modules • Controllers • Directives • Scope • Templates • Filters • Services • Dependency injection and container • Testability
AngularJSmodules • Allows to separate application in logical domains • Allows to minify dependencies and knowledge sharing between modules • Allows to introduce architecture limitations aka : – main module knows about controllers – main module knows about routing – controllers know about repositories (services) – main module knows nothing about repositories – controllers know nothing about routing
AngularJSmodules //declare module and its dependencies angular.module('myApp', ['ngAnimate','ngCookies']) //declaring controller in a module .controller("MainController",mainController) //running module configuration if needed .config(moduleConfiguration);
AngularJScontrollers • Attached to a DOM via ng-controller directive • Use them to: – Initiate and add behavior to the $scope – Retrieve data from services • Do not use for: – DOM manipulation – Data filtering – Share state with other parts of the application
AngularJScontrollers angular.module('app') .controller('Customers', [function() { var vm = this; vm.title = 'Customers'; vm.customers = [ {name: 'Customer 1'}, {name: 'Customer 2'}, {name: 'Customer 3'}, {name: 'Customer 4'} ]; }]); //VS angular.module('app') .controller('Customers', ['$scope', function($scope) { $scope.title = 'Customers'; $scope.customers = [ {name: 'Customer 1'}, {name: 'Customer 2'}, {name: 'Customer 3'}, {name: 'Customer 4'} ]; }]);
AngularJSDirectives • Markers for the DOM element • Use them to: – Attach behavior to the DOM element – Transform DOM • At the high level those can be treated as components which extend or change behavior of the DOM elements
AngularJSDirectives • Directives are declared as module.directive • Directives are invoked once so definition object instead of function is preferred • In order to avoid naming collisions prefix your directives and do not use standard ng as a prefix
AngularJSDirectives angular.module('app') //in html can be used as lo-directive //name expected to be in camel case in html each uppercase letter is prefixed with - .directive('loDirective', function() { return { //identifies matching rule // A-attribute, E – element, C - class name restrict: 'AEC', //isolating scope scope: { //equal for JS object info: '=info', // & for callback callback: '&', // @ for a value value: '@value' }, //replacing DOM element with own content replace:true, //if we need to wrap DOM element with some markup. //Original DOM is placed using ng-transclud transclude: false, //here is the template that is used for rendering templateUrl: 'my-customer-iso.html', //and that function would be called each time I am attached to the DOM element link:function(scope, element, attrs) { } //And by the way I can have my own controller, restrict access to specific controllers and other cool stuff };});
AngularJSScope • object that refers to the application model • arranged in hierarchical structure which mimic the DOM structure (scopes inheritance is done though prototype) • Provides API to: – Watch model mutations – Propagate model changes
AngularJSScope angular.module('app') .controller("TestController", ['$scope', function($scope){ //I can set values and use them in the view $scope.name = "Test"; $scope.count = 0; //I can subscribe to events which can be $emit(notify parents) //and $broadcast(notify children) $scope.$on('CustomEvent', function(name) { $scope.name = name; }); //I can $watch the changes //even in the collection through $watchCollection $scope.$watch('name',function(newValue, oldValue){ $scope.count++; }); //or I can apply changes if async operation is performed setTimeout(function(){ $scope.$apply(function(){ $scope.name = "Hey ya!!!"; })},200); }]);
AngularJS Templates • Written in HTML – Can contain directives – Can contain filters – Can contain form – Can contain specific markup {{expression}} • Can be loaded dynamically • Can be injected into other templates • Are loaded once per app • Are compiled on 1st load
AngularJS Workingwith forms • ng-model – bind element value to form control (ng-model=“user.name”) • Give form a name and mark it as novalidate • standard validation with formName.fieldname.$error • or use 3rd party libraries
AngularJS Templates <!-- ngController directive --> <body ng-controller="MyController as vm"> <!-- ngModel directive allows to bind to element values --> <input ng-model="foo" ng-model="vm.name" type="email"> <!-- This is going to be replaced with datepicker directive --> <datepicker ng-model="vm.date"></datepicker> <!-- this will call $scope.change once clicked and will have controller buttontext displayed inside --> <button ng-click="change()">{{vm.buttonText}}</button> <!-- or you can bind content with ngBind directive --> <span ng-bind="vm.buttonText"></span> <ul> <!-- here is the way I can iterate through collection with ngRepeat --> <!-- and change class depending on model value --> <li ng-repeat="item in vm.items track by id" ng-class="{active: item.active}"> <!-- and I can have expressions in the layout as well --> <button ng-click="item.active = !item.active">change state</button> <!-- and have custom templates if needed --> <div ng-include="item.templateUrl"></div> </li> </ul>
AngularJS Filters • Used to filter output • Used to format output • Filter is applied by using | in markup • Or can be injected in other object • Should return a function that will be evaluated
AngularJS Filters <script type="text/javascript"> //here is the way we register filder angular.module('myFilters', []).filter('checkmark', function() { //in the return function let's change the output return function(input) { return input ? 'True' : 'False'; }; }); </script> Search: <input ng-model="searchText"> <table> <tr><th>Name</th><th>Visited date</th><th>Active</th></tr> <!-- I can filter elements in array --> <tr ng-repeat="customer in customers | filter:searchText"> <td>{{customer.name}}</td> <!-- I can format output with standard filter --> <td>{{customer.lastVisitedDate | date:'yyyy-MM-dd'}}</td> <!-- or with custom --> <td>{{customer.active | checkmark }}</td> </tr> </table>
AngularJS Services • Used to share across application: – Data – Behavior • Services are lazy instantiated • Services are singletons • Remove code duplication • Can work with DOM if needed
AngularJS Services angular.module('app').factory('SampleRESTService', function ($resource) { //there we go let's use another service which provides full REST support return $resource('/api/sample/:id', { id: '@id' }); }) //let's inject the service .controller("TestController", ['$scope', 'SampleRESTService', function($scope, SampleRESTService){ $scope.tasks = SampleRESTService.query(); }]);
AngularJSDependencyinjection • Using the inline array annotation (prefered) is doing the constructor injection • Using $inject • Using naming convention (is not min safe) • Add ng-strict-di directive to avoid usage of naming convention
Dependencyinjection var MyController = function($scope, greeter) {}; //$inject annotation MyController.$inject = ['$scope']; myModule.controller('MyController', MyController); //array annotation myModule.controller('MyController',[ '$scope', MyController]); //naming annotation myModule.controller('MyController',MyController);
AngularJS Testability • Unit testing • End 2 end testing == Automated testing • Middleware testing == white box testing provides access to internal angular objects (directives) • Useful library angular-mocks
AngularJS Unit testing (controller) describe('Home controller test', function () { //loading module where controller is defined beforeEach(module('app.home')); //declaring variables that will be used in the tests var controller, scope, deferred; //creating items beforeEach(inject(function ($rootScope, $controller, $q) { deferred = $q.defer(); scope = $rootScope.$new(); //create the controller injecting the scope and the mocked service controller = $controller('Home', { $scope: scope, DashboardService: { getDashboard: function () { return deferred.promise; } } }); })); //once result is not returned let's check that initial data state is correct it('verifies NewMessagesCount is undefined', function () { expect(controller.NewMessagesCount === undefined); }); //Let's resolve value and see if it is correct it('verifies NewMessagesCount is correct', function () { deferred.resolve({ NewMessagesCount: 5 }); expect(controller.NewMessagesCount === 5); }); it('verifies that scope contains go and it is a function', function () { expect(scope.go === 'function'); }); });
AngularJS Unit testing (controller) describe('Dashboard factory tests', function () { //injecting module beforeEach(module('app.services')); //mocking dependcies beforeEach(function () { var Utility = {}; module(function ($provide) { $provide.value('Utility', Utility); }); }); var httpBackend, Factory; //injecting httpBackend for testing of http //injecting factory itself beforeEach(inject(function ($httpBackend, Factory) { httpBackend = $httpBackend; Factory = Factory; })); it('checks that object is not modified by service and proper API method is called', function () { //setting method we expect to be called and method response httpBackend.expectGET('api/Dashboard/').respond("Test"); var result = Factory.getDashboard(); //Verifying that all expected methods were called httpBackend.flush(); //verifying that result is returned as expected expect(result == "Test"); }); afterEach(function () { httpBackend.verifyNoOutstandingExpectation(); httpBackend.verifyNoOutstandingRequest(); }); });
Directory structure
First application • Specify ng-app directive to say that this is angular application
Sum Up • Provides big amount of features • Has everything for SPA development • Limits usage of other frameworks • Learning curve is being quite high
Useful componentsand links • https://angularjs.org/ • http://angular-ui.github.io/ - bootstrap components for angular
AngularJS.part1

AngularJS.part1

  • 1.
  • 2.
    AngularJSoverview • AngularJS isa JavaScript MVW framework made by Google for building complex client-side applications. • It provides everything for development of SPA out of the box
  • 3.
    AngularJScorefeatures • Modules • Controllers •Directives • Scope • Templates • Filters • Services • Dependency injection and container • Testability
  • 4.
    AngularJSmodules • Allows toseparate application in logical domains • Allows to minify dependencies and knowledge sharing between modules • Allows to introduce architecture limitations aka : – main module knows about controllers – main module knows about routing – controllers know about repositories (services) – main module knows nothing about repositories – controllers know nothing about routing
  • 5.
    AngularJSmodules //declare module andits dependencies angular.module('myApp', ['ngAnimate','ngCookies']) //declaring controller in a module .controller("MainController",mainController) //running module configuration if needed .config(moduleConfiguration);
  • 6.
    AngularJScontrollers • Attached toa DOM via ng-controller directive • Use them to: – Initiate and add behavior to the $scope – Retrieve data from services • Do not use for: – DOM manipulation – Data filtering – Share state with other parts of the application
  • 7.
    AngularJScontrollers angular.module('app') .controller('Customers', [function() { varvm = this; vm.title = 'Customers'; vm.customers = [ {name: 'Customer 1'}, {name: 'Customer 2'}, {name: 'Customer 3'}, {name: 'Customer 4'} ]; }]); //VS angular.module('app') .controller('Customers', ['$scope', function($scope) { $scope.title = 'Customers'; $scope.customers = [ {name: 'Customer 1'}, {name: 'Customer 2'}, {name: 'Customer 3'}, {name: 'Customer 4'} ]; }]);
  • 8.
    AngularJSDirectives • Markers forthe DOM element • Use them to: – Attach behavior to the DOM element – Transform DOM • At the high level those can be treated as components which extend or change behavior of the DOM elements
  • 9.
    AngularJSDirectives • Directives aredeclared as module.directive • Directives are invoked once so definition object instead of function is preferred • In order to avoid naming collisions prefix your directives and do not use standard ng as a prefix
  • 10.
    AngularJSDirectives angular.module('app') //in html canbe used as lo-directive //name expected to be in camel case in html each uppercase letter is prefixed with - .directive('loDirective', function() { return { //identifies matching rule // A-attribute, E – element, C - class name restrict: 'AEC', //isolating scope scope: { //equal for JS object info: '=info', // & for callback callback: '&', // @ for a value value: '@value' }, //replacing DOM element with own content replace:true, //if we need to wrap DOM element with some markup. //Original DOM is placed using ng-transclud transclude: false, //here is the template that is used for rendering templateUrl: 'my-customer-iso.html', //and that function would be called each time I am attached to the DOM element link:function(scope, element, attrs) { } //And by the way I can have my own controller, restrict access to specific controllers and other cool stuff };});
  • 11.
    AngularJSScope • object thatrefers to the application model • arranged in hierarchical structure which mimic the DOM structure (scopes inheritance is done though prototype) • Provides API to: – Watch model mutations – Propagate model changes
  • 12.
    AngularJSScope angular.module('app') .controller("TestController", ['$scope', function($scope){ //Ican set values and use them in the view $scope.name = "Test"; $scope.count = 0; //I can subscribe to events which can be $emit(notify parents) //and $broadcast(notify children) $scope.$on('CustomEvent', function(name) { $scope.name = name; }); //I can $watch the changes //even in the collection through $watchCollection $scope.$watch('name',function(newValue, oldValue){ $scope.count++; }); //or I can apply changes if async operation is performed setTimeout(function(){ $scope.$apply(function(){ $scope.name = "Hey ya!!!"; })},200); }]);
  • 13.
    AngularJS Templates • Writtenin HTML – Can contain directives – Can contain filters – Can contain form – Can contain specific markup {{expression}} • Can be loaded dynamically • Can be injected into other templates • Are loaded once per app • Are compiled on 1st load
  • 14.
    AngularJS Workingwith forms •ng-model – bind element value to form control (ng-model=“user.name”) • Give form a name and mark it as novalidate • standard validation with formName.fieldname.$error • or use 3rd party libraries
  • 15.
    AngularJS Templates <!-- ngControllerdirective --> <body ng-controller="MyController as vm"> <!-- ngModel directive allows to bind to element values --> <input ng-model="foo" ng-model="vm.name" type="email"> <!-- This is going to be replaced with datepicker directive --> <datepicker ng-model="vm.date"></datepicker> <!-- this will call $scope.change once clicked and will have controller buttontext displayed inside --> <button ng-click="change()">{{vm.buttonText}}</button> <!-- or you can bind content with ngBind directive --> <span ng-bind="vm.buttonText"></span> <ul> <!-- here is the way I can iterate through collection with ngRepeat --> <!-- and change class depending on model value --> <li ng-repeat="item in vm.items track by id" ng-class="{active: item.active}"> <!-- and I can have expressions in the layout as well --> <button ng-click="item.active = !item.active">change state</button> <!-- and have custom templates if needed --> <div ng-include="item.templateUrl"></div> </li> </ul>
  • 16.
    AngularJS Filters • Usedto filter output • Used to format output • Filter is applied by using | in markup • Or can be injected in other object • Should return a function that will be evaluated
  • 17.
    AngularJS Filters <script type="text/javascript"> //hereis the way we register filder angular.module('myFilters', []).filter('checkmark', function() { //in the return function let's change the output return function(input) { return input ? 'True' : 'False'; }; }); </script> Search: <input ng-model="searchText"> <table> <tr><th>Name</th><th>Visited date</th><th>Active</th></tr> <!-- I can filter elements in array --> <tr ng-repeat="customer in customers | filter:searchText"> <td>{{customer.name}}</td> <!-- I can format output with standard filter --> <td>{{customer.lastVisitedDate | date:'yyyy-MM-dd'}}</td> <!-- or with custom --> <td>{{customer.active | checkmark }}</td> </tr> </table>
  • 18.
    AngularJS Services • Usedto share across application: – Data – Behavior • Services are lazy instantiated • Services are singletons • Remove code duplication • Can work with DOM if needed
  • 19.
    AngularJS Services angular.module('app').factory('SampleRESTService', function($resource) { //there we go let's use another service which provides full REST support return $resource('/api/sample/:id', { id: '@id' }); }) //let's inject the service .controller("TestController", ['$scope', 'SampleRESTService', function($scope, SampleRESTService){ $scope.tasks = SampleRESTService.query(); }]);
  • 20.
    AngularJSDependencyinjection • Using theinline array annotation (prefered) is doing the constructor injection • Using $inject • Using naming convention (is not min safe) • Add ng-strict-di directive to avoid usage of naming convention
  • 21.
    Dependencyinjection var MyController =function($scope, greeter) {}; //$inject annotation MyController.$inject = ['$scope']; myModule.controller('MyController', MyController); //array annotation myModule.controller('MyController',[ '$scope', MyController]); //naming annotation myModule.controller('MyController',MyController);
  • 22.
    AngularJS Testability • Unittesting • End 2 end testing == Automated testing • Middleware testing == white box testing provides access to internal angular objects (directives) • Useful library angular-mocks
  • 23.
    AngularJS Unit testing(controller) describe('Home controller test', function () { //loading module where controller is defined beforeEach(module('app.home')); //declaring variables that will be used in the tests var controller, scope, deferred; //creating items beforeEach(inject(function ($rootScope, $controller, $q) { deferred = $q.defer(); scope = $rootScope.$new(); //create the controller injecting the scope and the mocked service controller = $controller('Home', { $scope: scope, DashboardService: { getDashboard: function () { return deferred.promise; } } }); })); //once result is not returned let's check that initial data state is correct it('verifies NewMessagesCount is undefined', function () { expect(controller.NewMessagesCount === undefined); }); //Let's resolve value and see if it is correct it('verifies NewMessagesCount is correct', function () { deferred.resolve({ NewMessagesCount: 5 }); expect(controller.NewMessagesCount === 5); }); it('verifies that scope contains go and it is a function', function () { expect(scope.go === 'function'); }); });
  • 24.
    AngularJS Unit testing(controller) describe('Dashboard factory tests', function () { //injecting module beforeEach(module('app.services')); //mocking dependcies beforeEach(function () { var Utility = {}; module(function ($provide) { $provide.value('Utility', Utility); }); }); var httpBackend, Factory; //injecting httpBackend for testing of http //injecting factory itself beforeEach(inject(function ($httpBackend, Factory) { httpBackend = $httpBackend; Factory = Factory; })); it('checks that object is not modified by service and proper API method is called', function () { //setting method we expect to be called and method response httpBackend.expectGET('api/Dashboard/').respond("Test"); var result = Factory.getDashboard(); //Verifying that all expected methods were called httpBackend.flush(); //verifying that result is returned as expected expect(result == "Test"); }); afterEach(function () { httpBackend.verifyNoOutstandingExpectation(); httpBackend.verifyNoOutstandingRequest(); }); });
  • 25.
  • 26.
    First application • Specifyng-app directive to say that this is angular application
  • 27.
    Sum Up • Providesbig amount of features • Has everything for SPA development • Limits usage of other frameworks • Learning curve is being quite high
  • 28.
    Useful componentsand links •https://angularjs.org/ • http://angular-ui.github.io/ - bootstrap components for angular