DEPENDENCY INJECTION 


SCOPES 


 That was EASY PEASY... 


 ...NOW 4 THE REAL STUFF 

BASE RULEs


  • no other global var than angular
  • one file per definition
  • dependency injection is brilliant: use it
  • testing IS AS EASY AS IT CAN GET: DO IT
  • DEDICATED MODULES FOR REUSABLE COMPONENTS


DEFINING A MODULE


angular.module('moduleName', [/* deps */]);


RETRIEVING A MODULE


angular.module('moduleName');

ADDING FUNCTIONALITY

angular.module('moduleName')
.animation()
.config()
.constant()
.controller()
.directive()
.factory()
.filter()
.provider()
.requires()
.run()
.service()
.value()
see: https://docs.angularjs.org/api/ng/type/angular.Module      

BOOTSTRAPPING




<body ng-app="my-module">
<div ng-view></div>
</body>


 WE NEED A ROUTE! 

DEFINING ROUTES


angular.module('myModule', ['ngRoute']);

ngRoute provides 
$routeProvider, $route and $routeParams

angular.module('myModule').config(['$routeProvider',
function($routeProvider) {
    $routeProvider
        .when('/detail/:id', {
            controller: 'DetailCtrl',
            template: 'detail.html'
        });
}]);




 WE NEED A CONTROLLER! 

DEFINING CONTROLLERS


angular.module('myModule.controllers').controller('DetailCtrl', ['$scope', 
function($scope) {
    // gluecode
}]);




 WE NEED A (VIEW) TEMPLATE! 

DEFINING A TEMPLATE


<div>
    <span ng-repeat="greetings as greeting">{{greeting|lowercase}}</span>
    <button ng-click="doSomething()">{{buttonText}}</button>
</div>

 DONE! 


 RELAX BEFORE WE GO AHEAD 

BUILTIN FILTERS


  • filter
  • currency
  • number
  • date
  • json
  • lowercase
  • uppercase
  • limitTo
  • orderBy

USING FILTERS



in template
<span>{{value|filter-name:arg1:arg2:...}}</span>

in javascript
$filter('filter-name')(value, arg1, arg2, ...)




see: https://docs.angularjs.org/api/ng/filter/filter & https://docs.angularjs.org/guide/filter     

BUILDING CUSTOM FILTERS



angular.module('myModule.filters').filter('filterName', [
function() {
    return function(input, arg1, arg2, arg3) {
        return input + arg1 + arg2 + arg3;
    }
}]);






see: https://docs.angularjs.org/guide/filter     






 DEFINITELY GOT THAT FILTER 

THING NOW 

BUILTIN DIRECTIVES


  • as elements (E)
    • a, form, input, script, select, textarea
  • as attributes (A)
    • ngApp
    • ngBlur
    • ngClick
    • ngDblClick
    • ngHref
    • ngIf
    • among 52 others

see: https://docs.angularjs.org/api/ng/directive     

USING DIRECTIVES



<div ng-repeat="thing in things">
    <span ng-dblclick="toggle(thing.id)">{{thing.description}}</span>
    <span ng-if="thing.additionalInfo">{{thing.additionalInfo}}</span>
    <a ng-href="thing.link.href">{{thing.link.text}}</a>
    <button ng-click="showDetailView(thing.id)"></button>
</div>

CUSTOM DIRECTIVES


angular.module('myModule.directives').directive('directiveName', [
function() {
    return {
        restrict: 'AEC',
        template: '<span>{{value}}</span>'
    }
}]);

in template

<div>
    <directive-name></directive-name>
</div>

compiled

<div>
    <span>some text</span>
</div>
see: https://docs.angularjs.org/guide/directive     







 THAT'S ALL? 

ISOLATING DIRECTIVE'S SCOPE


angular.module('myModule.directives').directive('directiveName', [
function() {
    return {
        scope: {}
    }
}]);

  • overriding does the job
  • now the directive has its own scope
    and we can pass in arguments


PASSING ARGUMENTS TO DIRECTIVES


<div>
    <directive-name an-argument="{{someValue}}"></directive-name>
</div>

angular.module('myModule.directives').directive('directiveName', [
function() {
    return {
        scope: {
            anArgument: '=' // also: @ / &
        },
        template: '<span>{{anArgument}}</span>'
    }
}]);

@&=???

@
attribute
=
binding
&
expression

see: http://onehungrymind.com/angularjs-sticky-notes-pt-2-isolated-scope/

DOM MANIPULATING DIRECTIVES


<div>
    <span directive-name></span>
</div>

angular.module('myModule.directives').directive('directiveName', [
function() {
    // this is javascript here so feel free to do whatever you want
    return function(scope, element, attrs) {
        element.text('hi');
    }
}]);

compiled
<div>
    <span>hi</span>
</div>








 TRANSCLUSION 







 TRANSCLUSION!!! !

TRANSCLUSION


<div>
    <directive-name><span>Some text</span></directive-name>
</div>

angular.module('myModule.directives').directive('directiveName', [
function() {
    return {
        transclude: true,
        template: '<div ng-transclude></div>'
    }
}]);

compiled
<div>
    <div><span>Some text</span></div>
</div>

DIRECTIVES WITH EVENT HANDLERS


angular.module('myModule.directives').directive('directiveName', [
function() {
    return function(scope, element, attr) {
        element.on('mouseenter', function(event) {
            event.preventDefault();
            // it's javascript, feel fre-- ahh you know...
        });
    }
}]);

DIRECTIVES THAT REQUIRE DIRECTIVES


angular.module('myModule.directives').directive('directiveOne', [
function() {
    return {
        scope: {},
        controller: function($scope) {
            $scope.method = function() {};
        }
    }
}])

angular.module('myModule').directive('directiveNameTwo', [function() {
    return {
        require: '^directiveOne',
        link: function(scope, elements, attrs, directiveOneController) {
            directiveOneController.method();
        }
    }
}])

 STILL WITH ME? 

BUILTIN SERVICES


  • $animate
  • $compile
  • $filter
  • $http
  • $location
  • $q
  • $timeout
  • among 17 others

USING A SERVICE


angular.module('myModule.controllers').controller('DetailCtrl', 
['$scope', '$http', 
function($scope, $http) {
    $scope.data;

    $http.get('yourapi/yourresponse.json')
         .success(function(data, status, headers, config) {
             $scope.data = data;
         })
         .error(function(data, status, headers, config) {
             // ...
         });
}]);

CUSTOM PROVIDERS: RECIPE TYPES



VALUE
CONSTANT
FACTORY
SERVICE
PROVIDER




see: https://docs.angularjs.org/guide/providers     


RECIPE TYPE: VALUE


definition
angular.module('myModule').value('foo', 'value value');

usage

angular.module('myModule.controllers').controller('CtrlName', 
['$scope', 'foo',
function($scope, foo) {
    $scope.name = foo;
}]);

<div>
    <span>{{name}}</span>
</div>

RECIPE TYPE: CONSTANT


definition
angular.module('myModule').constant('BAR', 'value value');

usage

angular.module('myModule.controllers').controller('CtrlName', 
['$scope', 'BAR',
function($scope, BAR) {
    $scope.name = BAR;
}]);

<div>
    <span>{{name}}</span>
</div>

RECIPE TYPE: FACTORY

definition
angular.module('myModule.s').factory('myFactory', [function() {
    var self = {};

    self.returnName = function() {
        return 'a name';
    }

    return self;
}]);

usage

angular.module('myModule').controller('CtrlName', ['$scope', 'myFactory',
function($scope, myFactory) { $scope.name = myFactory.returnName(); }]);

RECIPE TYPE: SERVICE

definition
function ConstFct() {
    this.someValue = 0;
    this.someMethod = function() {};
}
angular.module('myModule').service('myService', [ConstFct]);

usage

angular.module('myModule').controller('CtrlName', ['$scope', 'myService',
function($scope, myService) { $scope.name = myService.someMethod(); }]);

RECIPE TYPES: OVERVIEW







DONT'S

USING 

THE 

ROOTSCOPE


USE 

JQUERY 

AND 

APPLY()

EVERYWHERE


MANIPULATE 

THE 

DOM 

WITH 

THE

CONTROLLER


 SELECTOR 

INSIDE 

LINK()


BUSINESS 

LOGIC 

IN 

THE 

CONTROLLER





DO'S

STORE 

DATA

IN 

YOUR 

SERVICE


ONE 

FILE 

PER 

DEFINITION





 TOOLS? 





 BATARANG
(CHROME) 





 ANGULAR 

 (*STORM) 





 ANGULAR 

 (*STORM) 





 PLNKR.CO 







 FIN 

Made with Slides.com