Angular JS Egghead Videos Aprendis

“The dot”

  • Si dejamos ng-app=”” (vacío) podemos tener un comportamiento de data-binding inesperado.Por ejemplo no será lo mismo {{pepe.message}} que {{message}} cuando tengo varios controllers y data binding fuera de controllers. Esto se produce porque hay un parent scope y se producen efectos colaterales

Sharing data between controllers

  • Se hace creando un factory y metiendo como dependencia ese factory a los  controllers

[TRUCO: invertir una cadena:

message = split("").reverse().join("")

]

Filters

myApp.filter('reverse', function() {
    return function(text) {
        return text.split("").reverse().join("");
    }
});

html

{{message | filter}}

ngRepeat con filters

<input type="text" ng-model="search">
...
<tr ng-repeat="actor in avengerscast | filter: search">
	<td>{{actor.name}}</td>
  • Angular trae built-in filters como orderBy , limitTo , lowercase,  uppercase, etc

Directive : Basic behaviour

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

myApp.directive('superman', function() {
    return {
        restrict: "E",
        template: "<div>Super Indira</div>"
    }
})
	<div ng-app="myApp">
		<superman></superman>
	</div>

Directive : Basic behaviour

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

myApp.directive('enter', function() {
    return function(scope, element) {
        element.bind("mouseenter", function() {
            console.log("I'm inside of you");
        })
    }
})

myApp.directive('leave', function() {
    return function(scope, element) {
        element.bind("mouseleave", function() {
            console.log("Leaving");
        })
    }
})
	<h3>Basic behaviours</h3>
	<div ng-app="myApp">
		<div enter leave>My content</div>
	</div>

Directive : Parametrizando la directiva

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

myApp.directive('enter', function() {
    return function(scope, element, attrs) {
        element.bind("mouseenter", function() {
            element.addClass(attrs.enter);
        })
    }
})

myApp.directive('leave', function() {
    return function(scope, element, attrs) {
        element.bind("mouseleave", function() {
            element.removeClass(attrs.enter);
        })
    }
})
	<style type="text/css">
		.pane {
			text-transform: capitalize;
		}
	</style>

	<h3>Basic behaviours</h3>
	<div ng-app="myApp">
		<div enter="pane" leave>My content</div>
	</div>

Directives talking to controllers

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

myApp.controller('AppCtrl', function($scope) {
    $scope.loadMoreTweets = function() {
        alert("Loading Tweets!");
    }
    $scope.deleteTweets = function() {
        alert("Delete Tweets!");
    }
})

myApp.directive('enter', function() {
    return function(scope, element, attrs) {
        element.bind("mouseenter", function() {
            //console.log("Rolling overrrrr");
            //scope.loadMoreTweets();
            scope.$apply(attrs.enter);
        })
    }
})

myApp.directive('leave', function() {
    return function(scope, element, attrs) {
        element.bind("mouseleave", function() {
            element.removeClass(attrs.enter);
        })
    }
})
<h3>Directives talking to controllers</h3>
<div ng-app="myApp">
    <div ng-controller="AppCtrl">
        <div enter="loadMoreTweets()">Roll over to load more tweets</div>
        <br/>
        <br/>
        <br/>
        <div enter="deleteTweets()">Roll over to delete tweets</div>
    </div>
</div>

Directive to directive communication

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

myApp.directive('superhero', function() {
    return {
        restrict: 'E',

        controller: function($scope) {
            $scope.abilities = []

            this.addStrength = function() {
                $scope.abilities.push("strength");
            }
            this.addSpeed = function() {
                $scope.abilities.push("speed");
            }
            this.addFlight = function() {
                $scope.abilities.push("flight");
            }

        },

        link: function(scope, element) {
            element.bind('mouseenter', function() {
                console.log(scope.abilities);
            });
        }
    }
})

myApp.directive('flight', function() {
    return {
        require: 'superhero',
        link: function(scope, element, attrs, superHeroCtrl) {
            superHeroCtrl.addFlight();
        }
    }
})
myApp.directive('speed', function() {
    return {
        require: 'superhero',
        link: function(scope, element, attrs, superHeroCtrl) {
            superHeroCtrl.addSpeed();
        }
    }
})
myApp.directive('strength', function() {
    return {
        require: 'superhero',
        link: function(scope, element, attrs, superHeroCtrl) {
            superHeroCtrl.addStrength();
        }
    }
})
	<h3>Directives talking to controllers</h3>
	<div ng-app="myApp">
		<superhero flight speed strength> Superman</superhero>
	</div>

Isolating the Scope of a Directive

  • Surge la necesidad de poder utilizar la directiva en varios sitio de tu app.
  • Lo que vamos a hacer a continuación es aislar el scope exterior a la directiva del scope interno de la directiva. Y entonces mapear lo que nos interese del scope exterior en el scope interior. Esto se consigue con la opción “scope”:
angular.module('docsIsolateScopeDirective', [])
  .controller('Controller', ['$scope', function($scope) {
    $scope.naomi = { name: 'Naomi', address: '1600 Amphitheatre' };
    $scope.igor = { name: 'Igor', address: '123 Somewhere' };
  }])
  .directive('myCustomer', function() {
    return {
      restrict: 'E',
      scope: {
        customerInfo: '=info'
      },
      templateUrl: 'my-customer-iso.html'
    };
  });
<div ng-controller="Controller">
  <my-customer info="naomi"></my-customer>
  <hr>
  <my-customer info="igor"></my-customer>
</div>
Name: {{customerInfo.name}} Address: {{customerInfo.address}}

Note: These =attr attributes in the scope option of directives are normalized just like directive names. To bind to the attribute in<div bind-to-this="thing">, you’d specify a binding of =bindToThis.

For cases where the attribute name is the same as the value you want to bind to inside the directive’s scope, you can use this shorthand syntax:

...
scope: {
  // same as '=customer'
  customer: '='
},
...

https://docs.angularjs.org/guide/directive

Hay otros formas de comunicar el scope interno con el externo utilizando los símbolos ‘&’ y ‘@’

Directive: transclusion

https://docs.angularjs.org/guide/directive

Directive: modificando el DOM (angular.element)

Si queremos hacer manipulación del DOM desde la directiva  , mejor que intentar referenciar un elemento del DOM con la sintaxis de javascript , por ejemplo:

element.children(1).text("jaja");

es mejor tener crear una referencia completa al elemento que se quiere manipilar desde el principio de compilación de la directiva. Utilizamos para ello angular.element y se hace así:

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

app.controller("AppCtrl", function($scope) {})

app.directive("dumbpassword", function() {

    var validElement = angular.element('<div>{{model.input}}</div>');

    this.link = function(scope, element) {
        scope.$watch("model.input", function(value) {
            if (value == 'password') {
                validElement.text('jajajaja');
            }
        })
    }

    return {
        restrict: "E",
        replace: true,
        template: '<div> ' +
            '<input type="text" ng-model="model.input"> ' +
            '</div>',
        compile: function(tElem) {
            tElem.append(validElement);

            return link;
        }
    }
})
  <div ng-app="myApp">
    <dumbpassword></dumbpassword>
  </div>

Utilizar angular.element además nos permite realizar pruebas unitarias en angular mucho más facilmente.

La función compile monta el DOM que queremos sacar con la directiva. Esta función retorna la función link , si queremos que haya alguna claro.

Diferencia entre $scope y scope

Veamos el siguiente código:

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

app.controller("MyCtrl", function ($scope) {
    console.log($scope);
});

app.controller("MyCtrl2", ["$scope", function($scope) {}]);

ap.directive("myDirective", function () {
    return {
        link: function(scope) {
            console.log(scope);
        }
    }
});

El primer scope, el que va con el símbolo del dolar ($scope) , es un provider que se le pasa como dependencia al controlador. Otros  providers que se le pueden pasar con $http ,$parse , u otros que se cree el usuario. En este caso el orden no es importante ,ya que se busca los providers por nombre , independientemente del orden en que nos lo encontremos en la inyección de dependencia.

EL segundo scope , el que va sin símbolo de $ ,es un elemento que referencia el elemento scope , el espacio de data binding que utiliza angular. Aquí el orden de los parámetros sí es importante, por ejemplo no es lo mismo poner

function(scope, element, attrs)

a poner

function(element, scope, attrs)

El elemento scope siempre se espera en primer lugar.

Inyección de dependencias para protegerse del minificado

Hay una forma de pasar las dependencias a los elementos de angular para protegerse del minimificado de los js:

app.controller("MyCtrl", ["$scope", function($scope) {}]);

Se protege porque las cadenas no se minimifican.

Aquí el orden sí es importante , tiene que coincidir el orden de las cadenas con el orden de los providers que pongas en el function.

Ejemplos que necesitan localhost

Hay ejemplos de angularjs que necesitan de ejecutarse en un servidor por problemas de cross-domain-policy de los navegadores. Es decir que no pueden referenciar recursos alojados en otros servidores.

Para ello en algunos ejemplos he utilizado el sistema de build “gulp” para servir los ficheros. Como por ejemplo en “templateUrl”. En este caso se referencia un archivo “myTemplate.html”.

Además de que puede que no cargue la propia libreria de angular , si está referenciada a una url externa.

Haciendo routing con Angular

Se hace poniendo ng-view en el html y enchufando el modulo ngRoute en la configuración de nuestro módulo de angular:

Using ngRoute

In AngularJS 1.2.0 and later, ngRoute has been moved to its own module. If you are getting this error after upgrading to 1.2.x or later, be sure that you’ve installed ngRoute.

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

myApp.config(function($routeProvider) {
    $routeProvider.when('/',{
        templateUrl:'uno.html',
        controller:'UnoCtrl'
    })
})

myApp.controller('UnoCtrl', function($scope) {
    $scope.model = {
        message : "This is my ng-view app"
    };
})
<!DOCTYPE html>
<html>
<head>
    <!--<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js"></script>-->
    <script src="./bower_components/angular/angular.min.js"></script>
    <script src="./bower_components/angular-route/angular-route.min.js"></script>
    <script src="main.js"></script>
    <meta charset="utf-8">
    <title>JS Bin</title>
</head>
<body>

<div ng-app="myApp">

    <ng-view></ng-view>

</div>

</body>
</html>

d

fdd

f

ds

ds

d

iiuoouioiuo