Introducción a

AngularJS

Que es AngularJS?

HTML enhanced for web apps!
http://angularjs.org/
  • Browser mejorado especialmente adaptado para el desarrollo de aplicaciones web.
  • No hay que seguir ninguna API, nada que heredar, nada que llamar, solo Javascript.
  • Enlace de datos bi-direccional hace que el modelo de datos sea la unica fuente de verdad.
  • Permite al desarrollador extender el vocabulario del browser y convertir el HTML en un DSL.
  • Transforma el HTML en una declaracion descriptiva del funcionamiento de la aplicación.

Ejemplo: Lista de Tareas

<html ng-app>
<body id="ctrl" ng-controller="TodoCtrl">

  <ul>
    <li ng-repeat="todo in todos | orderBy: ['done','text']">
      <input type="checkbox" ng-model="todo.done">
      <span class="done-{{todo.done}}">{{todo.text}}</span>
    </li>
  </ul>

  <form ng-submit="addTodo()">
    <input type="text" ng-model="todoText" placeholder="new todo">
    <input type="submit" value="add">
  </form>

  <script src="js/angular.js"></script>
  <script>
  function TodoCtrl ($scope) {
    $scope.todos = [
      {text:'preparar slides', done:true},
      {text:'dar charla', done:false},
      {text:'tomar cerveza', done:false}
    ];
    $scope.addTodo = function (){
      $scope.todos.push({text:$scope.todoText, done:false});
      $scope.todoText = '';
    }
  }
  </script>

</body>
</html>
  Modelo
  Controlador
Vista

↑ Template

← Inyeccion de Dependecias

↑ Enlace de datos

Enlace de datos ↓

↓ Filtro

↓ Directiva

Enlace de Datos bidireccional

<html ng-app>
  <body ng-controller="MyCtrl">

    Enter your name: <input type="text" ng-model="name">
    <p>Hello {{name}}!</p>

    <button ng-click="reset()">reset</button>

    <script src="angular.js"></script>
    <script>
      function MyCtrl ($scope){
        $scope.name = "Diego";
        $scope.reset = function (){
          $scope.name = "";
        }
      }
    </script>
  </body>
</html>

Usando jQuery

<html>
  <body>
    Enter your name: <input type="text" id="model-name">
    <p>Hello <span id="name"></span>!</p>
    <button id="reset">reset</button>

    <script src="js/jquery.min.js"></script>
    <script>
      jQuery(function ($){
        function setName (msg){
          $('#name').text(msg);
          if ($modelname.val()!==msg){
            $modelname.val(msg);
          }
        }
        var $modelname = $('#model-name').on('keyup', function (){
          setName($(this).val());
        });
        $('#reset').on('click', function (){
          setName('');
        });
        setName('Diego');
      });
    </script>
  </body>
</html>

Filtros

<div ng-app ng-controller="MyCtrl">
  uppercase: {{sometext | uppercase}}<br>
  lowercase: {{sometext | lowercase}}<br>
  date: {{somedate | date:'dd-MM-yyyy HH:mm:ss'}}<br>
</div>

<script src="js/angular.js"></script>

<script>
  function MyCtrl ($scope) {
    $scope.sometext = "Hola";
    $scope.somedate = new Date();
  }
</script>
<div ng-app ng-controller="MyCtrl">
  <ul>
    <li ng-repeat="who in band | orderBy:'name' | filter:search">
    {{who.name}} - {{who.plays}}</li>
  </ul>
  <input type="text" ng-model="search.name" placeholder="por nombre...">
  <input type="text" ng-model="search.plays" placeholder="por instrumento...">
</div>
<script>
function MyCtrl ($scope) {
  $scope.band = [
    {name:'Robert Trujillo', plays:'Bajo'},
    {name:'Kirk Hammett', plays:'Guitarra solista'},
    {name:'James Hetfield', plays:'Guitarra ritmica'},
    {name:'Lars Ulrich', plays:'Bateria'}
  ];
}
</script>

Modulos

<div ng-app="MyApp" ng-controller="MyCtrl">
  <ul>
    <li ng-repeat="who in band">
    {{who.name}} - {{who.plays}}</li>
  </ul>
</div>

<script src="js/angular.js"></script>
<script>
var app = angular.module('MyApp', []);
app.controller('MyCtrl', function ($scope) {
  $scope.band = [
    {name:'Robert Trujillo', plays:'Bajo'},
    {name:'Kirk Hammett', plays:'Guitarra solista'},
    {name:'James Hetfield', plays:'Guitarra ritmica'},
    {name:'Lars Ulrich', plays:'Bateria'}
  ];
});
</script>

Servicios e Inyeccion de Dependencias

var app = angular.module("MyApp", []);

app.service("BandService", function () {
  var band = [
    {name:'Robert Trujillo', plays:'Bajo'},
    {name:'Kirk Hammett', plays:'Guitarra solista'},
    {name:'James Hetfield', plays:'Guitarra ritmica'},
    {name:'Lars Ulrich', plays:'Bateria'}
  ];
  this.list = function (){
    return band;
  }
});

app.controller('MyCtrl', function ($scope,BandService){
  $scope.band = BandService.list();
});

AJAX y Promesas

var app = angular.module("MyApp", []);

app.service("BandService", function ($http, $q) {
  this.list = function (){
    var deferred = $q.defer();
    $http.get('data.json').success(function (data){
      deferred.resolve(data);
    }).error(function (error){
      deferred.reject("Oops algo salio mal: " + error);
    });
    return deferred.promise;
  }
});

app.controller('MyCtrl', function ($scope,BandService){
    BandService.list().then(function (data){
      $scope.band = data;
    },
    function (error){
      $scope.errorMessage = error;
    });
});

Validaciones

<form name="myForm" ng-controller="MyCtrl" novalidate ng-submit="submit()">
  <input type="text" ng-model="user.name" required placeholder="nombre">
  <input type="email" ng-model="user.email" required placeholder="email">
  <input type="checkbox" ng-model="user.child"> Menos de 18?
  <input type="text" ng-model="user.age" ng-required="user.child"
    ng-maxlength="2" ng-pattern="/^[0-9]+$/" placeholder="edad (si es menor de 18)">
  <button ng-disabled="myForm.$invalid" >Enviar</button>
  <p>la forma es valida? {{myForm.$valid}}</p>
  <pre>{{user|json}}</pre>
</form>

<script>
var app = angular.module("MyApp", []);

app.controller('MyCtrl', function ($scope){
  $scope.submit = function(){
    alert('Enviado');
  }
});
</script>

Rutas y Vistas

var MyApp = angular.module('MyApp',[]);
MyApp.config(function ($routeProvider) {
  $routeProvider.
    when('/', {
      templateUrl: 'partials/list.html', controller: 'ListCtrl'
    }).when('/detail/:id', {
      templateUrl: 'partials/detail.html', controller: 'DetailCtrl'
    }).otherwise({redirectTo: '/'});
});
MyApp.controller('ListCtrl', function ($scope,BandService){
  $scope.band = BandService.list();
})
MyApp.controller('DetailCtrl', function ($scope,$routeParams,BandService){
  $scope.params = $routeParams;
  $scope.member = BandService.get($routeParams.id);
});

app.js

<ul>
  <li ng-repeat="who in band | orderBy:'name'">
    <a ng-href="#/detail/{{$index}}">{{who.name}}</a>
  </li>
</ul>

list.html

id: {{params.id}}<br>
name: {{member.name}}<br>
plays: {{member.plays}}<br>
<a href="#/list">List View</a><br>

detail.html

<div ng-app="MyApp">
  <div ng-view></div>
</div>

index.html

Directivas

app.directive('loadingBar', function ($rootScope){
  return {
    link: function (scope, element, attrs){
      element.addClass('progress progress-striped active');
      $rootScope.$on('$routeChangeStart', function (){
        element.fadeIn(500); //  jQuery
      });
      $rootScope.$on('$routeChangeSuccess', function (){
        element.fadeOut(500); //  jQuery
      });
    },
    template: '<div class="bar">Cargando...</div>'
  }
});
<div ng-view></div>
<div loading-bar></div>
var app = angular.module("MyApp", []);
app.directive('accordion', function (){
  return {
    restrict: 'EA',
    scope:{
      title:'@'
    },
    templateUrl: 'directives/accordion.html',
    transclude: true,
    link: function(scope, element, attr){
      scope.visible = false;
      scope.toggleContent = function(){
        scope.visible = !scope.visible;
      }
    }
  }
});

app.js

<dl>
  <dt ng-click="toggleContent()">Titulo: {{title}}</dt>
  <dd ng-show="visible" ng-transclude></dd>
</dl>

accordion.html

<div accordion title="{{model.title}}">Contenido: {{model.content}}</div>

Tips

  • Pensar como un server-side developer: como organizo mi aplicacion en componentes desacoplados, extensibles y fáciles de testear.
  • Las vistas deben ser declarativas y establecer QUE va a pasar (no importa COMO).
  • Los modelos representan el estado de los datos.
  • Los servicios se utilizan para crear tareas reutilizables.
  • La manipulacion del DOM se hace SOLAMENTE adentro de directivas.
  • Los controladores se usan como 'pegamento' de todos estos componentes.
  • TESTING - TDD

Gracias!

  • Diego Mónaco
  • http://dfmonaco.github.io/
  • @dfmonaco