Workshop 13: AngularJS Parte II

  • Published on
    14-Jan-2017

  • View
    337

  • Download
    1

Embed Size (px)

Transcript

  • Front End Workshops

    XII. AngularJS - Part 2

    Enrique Oriol Bermdezeoriol@naradarobotics.com

    Hctor Cantohcanto@visual-engin.com

  • Overview

    AngularJS lets you write client-side web applications as if you had a smarter browser

  • Overview

    AngularJS is easy

    AngularJS learning curve

    AngularJS

    is

    amazing... a

    nd

    hard as he

    ll

  • Content

    Digest Cycle

    Services

    Dependency Injection

    Routes

    Building Filters

    Building Directives

  • Digest Cycle

    the tech behind 2 way data binding magic

  • Digest cycle

    User event(ng-click)

    Sync work in controllers

    Async work in $http, $timeout and $interval

    scope.$apply Start from root scope

    Check allwatchers on

    scope

    more scopes? Update UI

    value changed

    no change

    switch to scope and continue checking

    everythingsdone

    $digest phase

  • Digest cycle

    What about async events?

    If you want to update view after receiving async event, you should force a $apply call.

    Dont do it directly: use $timeout

    // Somewhere, an async handler

    var handler = function(){

    $rootScope.$emit("changeContent");

    };

    //in your controller

    $rootScope.$on("changeContent", function(){

    console.log("rootScope event has been fired");

    $timeout(function(){ $scope.data = "Data should change"; });

    });

  • Services

    Where business logic lives

  • Services

    Services refers to injectable objects whose API is defined by the developer (not the framework)

    Reusable business logic, view independant

  • Services

    Singleton objects

    Once defined, it can be injected into other angular components like controllers, directives and services

  • Registering Services

    Module exposes 5 methods to instruct the injector how to evaluate our code

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

    .constant('myConstant', {})

    .value('myValue', {})

    .service('myService', function(){})

    .factory('myService', function(){})

    .provider('myService', function(){})

  • Registering Services

    Application life-cycle splits in 2 phases

    Configuration phase (app bootstrap) No services Configure and instantiate providers

    Run phase (after config) No Providers interaction Services start being created

  • For simple values of any type Do not accept DI / being configured Can be injected into the config function

    myApp.constant('SERVERS',{ DEVELOPMENT: "http://localhost:8080/app", PRODUCTION:"http://myDomain.com/app"});

    Constant

    myApp.config(function(SERVERS){

    console.log(SERVERS.PRODUCTION);

    });

    myApp.run(function(SERVERS){

    console.log(SERVERS.DEVELOPMENT);

    })

    Definition

    CONFIG USAGE RUN USAGE

    http://localhost:8080/app

  • Simple objects or primitives Do not accept DI / being configured

    myApp.value('randomize',function(){ return Math.floor(Math.random()*10000);})

    myApp.value('token','a1234567890');

    myApp.value('User',{'id': 'someId'})

    Value

    myApp.run(function(randomize, User){

    var num = randomize();

    User.id = num;

    });

    Definition

    USAGE

  • Constructor function that will be instantiated (internally invokes it with new) Cannot being configured Arguments represents DEPENDENCIES to be injected

    myApp.service('AuthBearer', ['token', function(token) {

    this.authValue = "bearer " + token;

    }]);

    Service

    myApp.run(function(AuthBearer){

    console.log(AuthBearer.authValue);

    })

    Definition

    USAGE

    myApp.value('token','a1234567890');

    TOKEN is INJECTED!!!

  • Uses DI, No config Allows service initialization

    myApp.factory('apiToken', ['$window', 'clientId', function apiTokenFactory($window, clientId) {

    var encrypt = function(data1, data2) {

    // NSA-proof encryption algorithm:

    return (data1 + ':' + data2).toUpperCase();

    };

    var secret = $window.localStorage.getItem('myApp.secret');

    var apiToken = encrypt(clientId, secret);

    return apiToken;

    }]);

    Factory

    myApp.run(function(apiToken)

    {

    console.log(apiToken);

    })

    Definition

    USAGE

  • Uses DI Exposes API for service config before app starts (config phase) $get method is a factory function, that creates our service

    myApp.provider('logger', function(){

    var logToConsole = false;

    this.enableConsole = function(flag){

    logToConsole = flag;

    };

    this.$get = function(){

    return {

    debug: function(msg){ if(logToConsole){ console.log(msg);} }

    };

    };

    })

    Provider

    Definition

  • Provider

    myApp.config(function(loggerProvider){

    loggerProvider.enableConsole(true);

    })

    CONFIGURATION

    myApp.run(function(logger){

    logger.debug('Hello world');

    })

    USAGE

    myApp.provider('logger', function(){

    var logToConsole = false;

    this.enableConsole = function(flag){

    logToConsole = flag;

    };

    this.$get = function(){

    return {

    debug: function(msg){ if(logToConsole){ console.log(msg);} }

    };

    };

    })

    REMEMBER

  • myApp.provider('logger', function(){

    var logToConsole = false;

    this.enableConsole = function(flag){

    logToConsole = flag;

    };

    this.$get =

    function(){

    return {

    debug: function(msg){

    if(logToConsole){ console.log(msg);}

    }

    };

    };

    });

    Provider shorthands

    Provider

    Factory

    Service

  • Dependency Injection

    Pervasive pattern along angular

  • Dependency Injection

    Software design pattern that deals with how

    components get hold of their dependencies

  • Dependency Injection

    The Angular injector subsystem is in charge of

    creating components,

    resolving their dependencies,

    and providing them to other components as requested.

  • Dependency Injection

    The key players are the

    provide & injector

    services

    The magic behind

  • Dependency Injection

    We register our code on the

    injector with the provide service

    https://docs.angularjs.org/api/auto/service/$provide

    The magic behind

  • Dependency Injection

    We must provide a

    key as the first argument

    The magic behind

  • Dependency Injection

    The injector keeps our code in an

    internal object called

    providerCache

    The magic behind

  • Dependency Injection

    We use the injector to

    retrieve object instances

    https://docs.angularjs.org/api/auto/service/$injector

    The magic behind

  • Dependency Injection

    First time we inject a service, the

    injector evaluates the code

    and stores the result

    in an instanceCache object

    The magic behind

  • Dependency Injection

    When injecting a service,

    injector always look first

    into instanceCache

    The magic behind

  • Dependency Injection

    Thats why our services

    are singletons

    The magic behind

  • Dependency Injection

    Components, controllers and run

    accept any service DI (not providers)

    config can be injected

    with provider and constant components

    How to use it

  • Dependency Injection

    3 ways to use DI:

    Implicit Annotation

    $inject Property Annotation

    Inline Array Annotation

    How to use it

  • Dependency Injection

    Implicit Annotation

    How to use it

    myApp.controller('MyCtrl', function($scope, logger) {

    // ...

    });

    The Simplest way

    If we minify our code, service names as arguments will be renamed, and app will

    break.var MyController = function($scope, logger) {

    // ...

    }

    myApp.controller('MyCtrl', MyController]);

  • Dependency Injection

    $inject property Annotation

    How to use it

    var MyController = function($scope, logger) {

    // ...

    }

    MyController.$inject = ['$scope', 'logger'];

    myApp.controller('MyCtrl', MyController);

    The Long way

    Order of parameters must MATCH

  • Dependency Injection

    Inline Array Annotation

    How to use it

    myApp.controller('MyCtrl', ['$scope', 'logger', function($scope, logger)

    {

    // ...

    }]);

    The prefered way

    var MyController = function($scope, logger) {

    // ...

    }

    myApp.controller('MyCtrl', ['$scope', 'logger',

    MyController]);Order of parameters must MATCH

  • Routes

    Navigating Through Views

  • Routes

    2 common routing libs

    ngRoute https://docs.angularjs.org/api/ngRoute/service/$route Official Separated in ngRoute module Only one navigation view per application

    ui-router https://angular-ui.github.io/ui-router/ Community chosen More powerful More flexible

    https://docs.angularjs.org/api/ngRoute/service/$routehttps://angular-ui.github.io/ui-router/

  • ui-router

    based on states concept

    can use routes

    other behaviours

  • ui-router

    What is a state?

    A place in the app, in terms of UI and navigation

    Describes how the UI looks like and what does at that place

    States are bound to named, nested and parallel views

  • ui-router

    Installation

    $ bower install angular-ui-router

    angular.module('myApp', ['ui.router']);

    Get Package

    Include Script

    Import Module

  • ui-router

    Simple State

    angular.module('myApp', ['ui.router'])

    .config(function($stateProvider){

    $stateProvider

    .state('home', {

    url: '/home.html',

    templateUrl: 'views/home.html'

    });

    });

    Defining State Directive ui-view

  • ui-router

    $stateProvider

    $state is a service defined with provider method

    that gives us $stateProvider to prepare $state at config phase

    $state is the ui-router service to handle states

    http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$state

    http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$statehttp://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$state

  • ui-router

    Navigation

    Navigate!

    Navigate!

    NAV THROUGH VIEW NAV THROUGH CONTROLLER

    myApp.controller('Ctrl', function($scope, $state){

    $scope.navigate = function(){

    $state.go('home');

    }

    })

    link href also works, but AngularJS introduces #:

    http://codepen.io/-kaik-/pen/wMRYGE

  • ui-router

    Some state options

    .config(function($stateProvider){

    $stateProvider

    .state('home', {

    url: '/home.html',

    templateUrl: 'views/home.html',

    controller: 'HomeCtrl',

    data:{

    level: 'PRO'

    }

    });

    });

    .controller('HomeCtrl', function($scope, $state){

    $scope.message = "Hi world!, you belong to " +

    $state.current.data.level + " level";

    })

    http://codepen.io/-kaik-/pen/YwdJLe

  • ui-router

    Parameters

    .config(function($stateProvider){

    $stateProvider

    .state('home', {

    url: '/home/:username',

    templateUrl: 'views/home.html',

    controller: 'HomeCtrl'

    });

    });

    .controller('HomeCtrl', function($scope, $stateParams){

    $scope.message = "Hi " + $stateParams.username;

    })

    .controller('Ctrl', function($scope, $state){

    $scope.navigate = function(){

    $state.go('home', {username: "Marqus"});

    }

    })

    Navigate using ui-sref

    http://codepen.io/-kaik-/pen/obJaJp

  • ui-router

    .config(function($stateProvider){

    $stateProvider

    .state('home', {

    url: '/home/:username',

    templateUrl: 'views/home.html',

    controller: 'HomeCtrl',

    data:{ level: 'PRO'}

    })

    .state('home.profile', {

    url: '/profile',

    templateUrl: 'views/profile.html',

    controller: 'ProfileCtrl'

    })

    });

    Nested views.controller('HomeCtrl', function($scope, $state, $stateParams){

    $scope.homeMsg = "Home, sweet home " + $stateParams.username;

    })

    .controller('ProfileCtrl', function($scope, $state, $stateParams){

    $scope.user = {

    name: $stateParams.username,

    level: $state.current.data.level

    };

    })

    http://codepen.io/-kaik-/pen/zryMrd

  • ui-router

    .config(function($stateProvider){

    $stateProvider

    .state('home', {

    views:{

    "": { template: '' },

    "header": {

    templateUrl: 'views/header.html',

    controller: 'HeaderCtrl'

    },

    "footer": { template:"All rights reserved" }

    }

    })

    })

    Named views

    ui-view directive can be used as Element or as Attribute

  • ui-router

    .config(function($stateProvider, $urlRouterProvider){

    $stateProvider.state(...)

    $urlRouterProvider.otherwise('#/home') //this is a URL

    })

    Redirections

    .run(function($state){

    $state.transitionTo('home);

    });

    Always that Url is unknown

    At Launch

  • use state property abstract:true

    abstract states cannot be directly activated

    abstract states can have controller

    Useful for nested views

    ui-router

    Abstract states

  • abstract states

    nested states

    named states

    ui-router

    Lets see a full example with:

    http://codepen.io/-kaik-/pen/JGwewe

  • ui-router

    State resolve and callbacks

    .state('home', {

    resolve: {user: function(){}}, //where function returns a promise

    onEnter: function(user){},

    onExit: function(user){}

    });

  • ui-router

    staterequested $stateChangeStart

    $stateChangeSuccess

    ui-view kicks in$viewContentLoaded

    Done

    State Life Cycle & Events

    $stateChangeError

    $stateNotFound

    onload function

  • Filters

    AND $Filter.(filter)

  • Filters

    Pre-defined filters: currency, number, date, lowercase, orderBy, filter We can apply several filters to the same expression

    Format:{{ expression | filter:argument1:argument2 | filter2 }}

    Some examples:{{ 5 | currency: , 2}} >> 5.00{{ 5 | currency: , 2}} + >> 5.00 {{ hello | uppercase }} >> HELLO

  • Custom Filter

    app.filter('filtername', function() { return function(input) { return input + some text; };

    DOM filter{{ input_expression | filtername }}

    Controller filter$filter(filtername)(input_expression, argument);

    http://codepen.io/hectorcanto/pen/LGqJpa

  • How filters work Every binded expression will have a $watcher.

    So dont spare on filters if they improve your life. Watchers are checked every digest loop, but only run on changes.

    Filters take as much time as the function they run. Optimization

    Use one-way binding (::value) If something wont change, pre-process it, dont filter it. Avoid DOM filters when possible Beware of dependencies, dont introduce state. Preferably with strings

    http://www.alexkras.com/11-tips-to-improve-angularjs-performance/

    https://www.binpress.com/tutorial/speeding-up-angular-js-with-simple-optimizations/135

    4

    http://www.alexkras.com/11-tips-to-improve-angularjs-performance/http://www.alexkras.com/11-tips-to-improve-angularjs-performance/https://www.binpress.com/tutorial/speeding-up-angular-js-with-simple-optimizations/135https://www.binpress.com/tutorial/speeding-up-angular-js-with-simple-optimizations/135

  • Stateful Filters

    Typical case: {{ 'TRANSLATIONID' | translate }} The ID never changes but the language does. Used on ng-translate.

    angular.module('myApp', []).filter('translate', ['translationService', function (translationService) { function translate(input) { chain_translated += translationService.getChain(input); return chain_translated; } translate.$stateful = true; return translate;}]);http://blog.thoughtram.io/angularjs/2014/11/19/exploring-angular-1.3-stateful-filters.html

    http://blog.thoughtram.io/angularjs/2014/11/19/exploring-angular-1.3-stateful-filters.htmlhttp://blog.thoughtram.io/angularjs/2014/11/19/exploring-angular-1.3-stateful-filters.html

  • Directives

    DOM Manipulation

  • Directives

    Main purpose:Directives are markers on a DOM element that tell Angulars HTML compiler to

    attach a certain behaviour to it (via event listeners).Structure Snake and camelCase naming format Restrict roles Template vs. TemplateURL Controller and controllerAs Scope isolation Functionshttp://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-i-the-fundamentals

    http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-i-the-fundamentalshttp://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-i-the-fundamentals

  • By intuition yo...

Recommended

View more >