Angular logo

CREI Utn Rosario

https://github.com/aotaduy

profile

Ing. Andres Otaduy

http://aotaduy.github.io/presentacion-angular-crei/

HTML + HTTP Paginas Estaticas

Primer pagina web Emulador

Evolucion FrontEnd

HTML + Imagenes + Tablas

Hypermedia: HTML + Imagenes + Tablas

Web Applications

Perl, ASP, PHP, Apache, MySQL

Evolucion

Single Page Applications

NodeJs, Java, C#, MongoDB, Javascript, REST API

SPA: Single Page Applications

  • Servicios REST
  • Frameworks Front End Angualr, ember, knockout, React
  • Separacion de Intereses
  • Division de Backend / Frontend
  • Mobile o Mobile First
  • Examples

Javascript

Javascript
  • Uno de los lenguajes mas usados e incomprendidos del mundo
  • Obligatorio para programar en el browser
  • Interfaz Con el DOM
  • Sintaxis de C, Semantica de Scheme

Javascript influencias

  • Scheme
  • Java
  • Self
  • Perl

Javascript Good Parts

  • Loose Typing
  • Objetos Dinamicos
  • Funciones Lambda
  • Objetos Literales
  • Herencia prototipica
  • Es facil!

Funciones Lambda

var cuad, cubo, array = [1,2,3,4];
cuad = function(a){
  return a * a;
};
cubo = function(a) {
  return cuad(a) * a;
};

array.map(cuad) + array.map(cubo);
console.log(array.reduce(0, suma));

function suma(a,b) {
  return a + b;
}

Objetos dinamicos

var object = {name: 'Jon'};
object.lastName = 'Smith';
object.print = function(){
  console.log('Name:', this.name);
  console.log('LastName:', this.lastName)};
object.print();

Objetos Literales

{
  "glossary":{
    "title":"example glossary",
    "GlossDiv":{
      "title":"S",
      "GlossList":{
        "GlossEntry":{
          "ID":"SGML",
          "SortAs":"SGML",
          "GlossTerm":"Standard Generalized Markup Language",
          "Acronym":"SGML",
          "Abbrev":"ISO 8879:1986",
          "GlossDef":{
            "para":"A meta-markup language, used to create markup languages such as DocBook.",
            "GlossSeeAlso":[
              "GML",
              "XML"
            ]
          },
          "GlossSee":"markup"
        }
      }
    }
  }
}

Javascript Bad Parts

  • Variables Globales
  • Interfaz con el DOM
  • Insercion de punto y coma
  • comparaciones == !=
  • Es facil!

Correr JS

  • Embebido
  • Scripts
  • NodeJs

Angular.js

  • Framework front end Opinionated
  • Templates Declarativos
  • Extiende HTML
  • Componentes
  • Testeabilidad
  • Alto Nivel
  • Aplicaciones ABM
  • MVC - MVVM
  • Facil de instalar
  • Algunas Desventajas

Templates Declarativos

Extiende HTML

<div class="row">
    <h2>Search movies</h2>
</div>
<div class="row">
    <div class="col-xs-12">
        <search-box autocomplete="searchVm.topMovieNames" search-callback="searchVm.updatedSearch"></search-box>
        <movie-listing  movies="searchVm.movies"></movie-listing>
    </div>
</div>
<div class="row">
</div>
<home-footer></home-footer>

Componentes

Testeabilidad


Angular.js

  • Alto Nivel
  • Aplicaciones ABM
  • MVC - MVVM
  • Facil de instalar
  • Algunas Desventajas

Como Empezar

Cargar el script de angular, usar la directiva ng-app

<!doctype html>
                <html ng-app>
                <head>
                <title>My Angular App</title>
                <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
                </head>
                <body>
                <!-- Add your template here -->
                </body>
                </html>

Estructura

Views - Templates - Directivas

  • Two way binding {{}}
  • Directivas del Framework
    • ng-app
    • ng-init
    • ng-model
    • ng-if, ng-show
    • ng-repeat
    • ng-class

words

Data Binding

  1. Compilacion del template
  2. Cambio en la vista actualiza el modelo
  3. Cambio en el modelo actualiza la vista ir a 2
  4. Cuando modelo y vista estan estables render del DOM

Todo List

Filters

Es una funcion sin efectos secundarios que toma un valor del template o de otro filtro y lo reemplaza por otro.

Sintaxis: {{expresion | filter1: param1 : param2 | filter2 : param21 | filter3 ...}}

  • currency
  • number
  • orderBy
  • json
  • limitTo
  • filter

Controllers

MVC Model View Controller vs MVVM Model View ViewModel

scope

  • El contexto de ejecucion de una view
  • Puede alojar estado y comportamiento
  • Organizado jerarquicamente
  • Puede disparar eventos
  • Encargado del Two way binding

Controller

  • Aumentan el scope con funciones y estado
  • Setean el estado inicial e una vista
  • ng-controller
  • Controller y Scope
  • Estilo
  • ng-include

Ejemplo

Directivas Basicas

Las directivas son marcadores en el DOM (elementos, atributos, classes o comentarios). Para extender el HTML, modificar el comportamiento de los elementos o de sus hijos.

Angular compila en tiempo de ejecucion los templates buscando directivas y agregando comportamiento a los elementos del DOM.

Directivas - Componentes

  • Tipo de la Directiva EAC
  • Template
  • Scope
  • controllerAs
  • bindToController

Api completa en https://docs.angularjs.org/api/ng/service/$compile

Ejemplo

  angular
        .module('moviesApp')
        .directive('searchBox', searchBoxDirective);
    function searchBoxDirective() {
        return {
            restrict: 'E',
            // template: '
', templateUrl: 'app/components/search-box/search-box.html', scope: { query: '=?', autocomplete: '=', searchCallback: '=' }, bindToController: true, controller: 'SearchBoxController', controllerAs: 'searchVm' }; }

Ejemplo HTML

<div class="row">
    <h2>Search movies</h2>
</div>
<div class="row">
    <div class="col-xs-12">
        <search-box autocomplete="searchVm.topMovieNames" search-callback="searchVm.updatedSearch"></search-box>
        <movie-listing  movies="searchVm.movies"></movie-listing>
    </div>
</div>
<div class="row">
</div>
<home-footer></home-footer>

Otros tipos de directivas

Las veremos mas adelante.

  • Manipulacion del DOM
  • Compilacion
  • Transclusion

Servicios Angular

Son objetos singleton no visuales con lazy initialization, que se pueden inyectar a traves del sistema de injeccion de dependencias en otros componentes.

  • Comunicar Directivas y Controladores
  • Compartir y Reusar codigo
  • Acceder a las API del browser
  • Manejar la comunicacion HTTP

Servicios Angularjs

Servicios de Angular

  • Browser: $window, $location, $anchorScroll, $timeout
  • Angular: $filter(‘limitTo’), $controller, $log, $rootScope, $scope
  • Templates: $compiler, $parse, $interpolate
  • Promises: $q
  • API Calls: $http, $resource, $xhrFactory
  • Seguridad: $sce, $sceDelegate

Injeccion de Dependencias

Inversion de control, para configurar y testear

  • Dependencia de Creacion: collection = new Array()
  • Variable Global: window.location = ‘http://www.google.com’
  • PAsar como parametro: function factory(collectionClass){ collection = new collectionClass();}

Sintaxis de DI

    // Reflection notation
    angular.module('website').
    controller('PageController', PageController);
    function PageController($scope, $timeout){};

    // $inject notation
    angular.module('website').
    controller('PageController', PageController);
     PageController.$inject = [‘$scope’, ‘$timeout’];
     function PageController($scope, $timeout){};

    // Array notation
    angular.module('website').
    controller('PageController',
      [‘$scope’, ‘$timeout’, function($scope, $timeout){}]
    );
    

Creacion de un servicio

(function() {
    angular
        .module('webapp')
        .factory('socialSharing', service);

    service.$inject = [
        '$window'
    ];

    function service($window) {
        var service = this;
        service.shareWithNetwork = shareWithNetwork;
        return service;

        function shareWithNetwork(name, url, networkFun, label) {
            if (!$window.plugins || !$window.plugins.socialsharing) {
              return reportShareError(label);
            }
            $window.plugins.socialsharing[networkFun](name, null, url, angular.noop, function () {
              reportShareError(label);
            });
          }
        }
}

$http

$http permite realizar llamadas http en sus diferentes metodos. devolviendo una promesa por el resultado de la llamada.


  // Simple GET request example:
  $http({
    method: 'GET',
    url: '/someUrl'
  }).then(function successCallback(response) {
      // this callback will be called asynchronously
      // when the response is available
    }, function errorCallback(response) {
      // called asynchronously if an error occurs
      // or server returns response with an error status.
    });

$http respuesta

  • data – {string|Object} response body
  • status – {number} – HTTP status code of the response.
  • headers – {function([headerName])} – Header getter function.
  • config – {Object} – The configuration object
  • statusText – {string} – HTTP status text of the response.

Shortcut

$http.get('/someUrl', config).then(successCallback, errorCallback);
$http.post('/someUrl', data, config).then(successCallback, errorCallback);

$http ejemplos

Promesas - $q

Una promesa es un objeto que representa un valor que puede estar disponible ahora, en el futuro o nunca.

Trabajamos con promesas para computar valores de forma asincrona tomando acciones cuando el valor esta disponible o cuando se produce un error.

Promesas - $q

Una promesa puede tener tres estados, pendiente (pending), resuelto (resolved), rechazado(rejected).

Usando then(), catch(), finally() podemos tomar acciones ante los diferentes estados de la promesa.

Promesas


function(aPromise, $q) {
  aPromise
    .then(successCallback, errorCallback)
    .catch(errorCallback)
    .finally(finallyCallback);
  rejected = $q.reject();
  resolved = $q.when();
  newPromise = $q.all([rejected, resolved, aPromise]);
  newPromise = $q.race([rejected, resolved, aPromise]);
  //Create promises
  deferred = $q.defer();
  deferred.resolve(aValue);
  deferred.reject(aValue);
  return deferred.promise;
}

antipatterns

Angular 2 Intro

  • TypeScript -> ES6
  • Modules Ng and ES6
  • Componentes
  • Templates
  • Bootstraping
  • Data Binding
  • Directivas
  • Servicios
  • HTTP

Angular 2 Pros

  • TypeScript and ES6
  • Arquitectura de componentes
  • Modularidad (ES6)
  • RxJs REactive programming
  • Performance
  • Arquitectura mas simple
  • CSS Modular
  • Mejor deteccion de cambios

Angular 2 Cons

  • Recien lanzado
  • TypeScript
  • Muchos cambios respecto de Angular.js
  • Complejidad
  • Sintaxis de los templates
  • Eliminacion de scope $scope

Arquitectura

Componentes

  • Se definen como una clase anotada
  • La instancia se vincula al template
  • Dependencias explicitas y modulares
  • stylesheets
  • Usa Shadow Dom
  • Lifecycle hooks

Sintaxis de un componente

import { Component } from '@angular/core';
          import {TodoItem} from './todo-item'

          @Component({
            selector: 'app-root',
            templateUrl: 'app.component.html',
            styleUrls: ['app.component.css']
          })
          export class AppComponent {
            title = 'app works!';
            list: Array<TodoItem>;
            item: TodoItem;

            constructor() {
              this.list = [];
              this.item = new TodoItem;
            }

            add( anItem: TodoItem) {
              this.list.push(anItem);
              this.item = new TodoItem;
            }

            remove( index: number) {
              this.list.splice(index,1);
            }
          }

Templates


          <h1 [ngClass]="{'big': list.length > 5}" >Todo {{list.length}}</h1>
  <input type="text" [(ngModel)]="item.text">
  <input type="button"  value="Add" (click)="add(item)">
  <ul>
    <li
    [ngClass]="{'done': todoItem.done}" \
    *ngFor="let todoItem of list; let i = index">
      <input type="checkbox" [(ngModel)]="todoItem.done">
        {{todoItem.text}}
        <input
          *ngIf="todoItem.done"
          (click)="remove(i)"
          type="button"
          name="name"
          value="X">
      </li>
  </ul>
          

Elementos de un template

  • Propiedades del DOM y eventos no atributos html
  • bindings {{}} sin efectos secundarios: Expresiones
  • atributos []
  • eventos (): Statements $event displnible
  • Two Way [()]
  • Directivas
  • Componentes
  • Pipes

{{Template Expression}}

  • sin efectos secundarios =, new, ++ ;
  • el scope es la instancia del componente
  • no hay un espacio de nombres global
  • Quick
  • Simplicity
  • Idempotent

Template Statements

Bindings de atributo, clase y estilo

<table border=1>
  <!--  expression calculates colspan=2 -->
  <tr><td [attr.colspan]="1 + 1">One-Two</td></tr>

  <!-- ERROR: There is no `colspan` property to set!
    <tr><td colspan="{{1 + 1}}">Three-Four</td></tr>
  -->

  <tr><td>Five</td><td>Six</td></tr>
</table>

Binding de Clase

<!-- toggle the "special" class on/off with a property -->
<div [class.special]="isSpecial">The class binding is special</div>

<!-- binding to `class.special` trumps the class attribute -->
<div class="special"
     [class.special]="!isSpecial">This one is not so special</div>

Binding de Estilo

<button [style.color] = "isSpecial ? 'red': 'green'">Red</button>
<button [style.background-color]="canSave ? 'cyan': 'grey'" >Save</button>
<button [style.font-size.em]="isSpecial ? 3 : 1" >Big</button>
<button [style.font-size.%]="!isSpecial ? 150 : 50" >Small</button>
          

Directivas del framework

  • Muy pocas
  • NgClass, NGStyle
  • *NgId *NgFor *NgSwitch

Referencias de template


          <!-- phone refers to the input element; pass its `value` to an event handler -->
  <input #phone placeholder="phone number">
  <button (click)="callPhone(phone.value)">Call</button>

  <!-- fax refers to the input element; pass its `value` to an event handler -->
  <input ref-fax placeholder="fax number">
  <button (click)="callFax(fax.value)">Fax</button>

Modulos y NgModule

export class ZipCodeValidator implements StringValidator {
              isAcceptable(s: string) {
                  return s.length === 5 && numberRegexp.test(s);
              }
          }
import { ZipCodeValidator } from "./ZipCodeValidator";

          let myValidator = new ZipCodeValidator();
 NgModule(options : {
constructor(options?: NgModuleMetadataType)
providers : Provider[]
declarations : Array<Type<any>|any[]>
imports : Array<Type<any>|ModuleWithProviders|any[]>
exports : Array<Type<any>|any[]>
entryComponents : Array<Type<any>|any[]>
bootstrap : Array<Type<any>|any[]>
schemas : Array<SchemaMetadata|any[]>
}) 

Subcomponentes Input y Output

import { Component, Input, Output, EventEmitter } from '@angular/core';

          import {TodoItem} from './todo-item';

          @Component({
              selector: 'todo-line',
              template: `
              <input type="checkbox" [(ngModel)]="item.done">
      {{item.text}}
      <input type="button" name="name" value="X" (click)="remove(item)">
          `
          })
          export class TodoLine {
            @Input() item: TodoItem;
            @Output() removeRequested: EventEmitter = new EventEmitter();

            remove( index: number) {
              this.removeRequested.emit(this.item)
            }
          }