AngularJS
Temas avanzados
Álvaro Alonso
Inicialización manual
 Angular se inicializa automáticamente cuando el DOM está cargado
completamente
 En ese momento busca la directiva ngApp y si la encuentra
 Carga el módulo indicado por la directiva
 Crea el inyector para la aplicación
 Compila el DOM
 Pero también se puede inicializar Angular de forma manual
 Mediante angular.bootstrap(…)
2
Inicialización manual
3
<!doctype html>
<html>
<body>
<div ng-controller="MyController">
Hello {{greetMe}}!
</div>
<script src="http://code.angularjs.org/snapshot/angular.js"></script>
<script>
angular.module('myApp', [])
.controller('MyController', ['$scope', function ($scope) {
$scope.greetMe = 'World';
}]);
angular.element(document).ready(function() {
angular.bootstrap(document, ['myApp']);
});
</script>
</body>
</html>
Dependency Injection
 Inline Array Annotation (recomendada)
 $inject Property Annotation
 Implicit Annotation (no funciona con código minificado!!!)
Formas alternativas
4
someModule.controller('MyController', ['$scope', 'greeter', function($scope, greeter) {
// ...
}]);
var MyController = function($scope, greeter) {
// ...
}
MyController.$inject = ['$scope', 'greeter'];
someModule.controller('MyController', MyController);
someModule.controller('MyController', function($scope, greeter) {
// ...
});
Dependency Injection
 Con inicialización automática
 Con inicialización manual
Evitar Implicit Annotation
5
<!doctype html>
<html ng-app="myApp" ng-strict-di>
<body>
I can add: {{ 1 + 2 }}.
<script src="angular.js"></script>
</body>
</html>
angular.bootstrap(document, ['myApp'], {
strictDi: true
});
Jerarquía de $scope
 Cada aplicación de angular tiene
 Un único $rootScope
 Varios $scope hijos
 Cuando se crea un nuevo scope éste se añade como hijo de su scope padre
 Así crea un árbol de scopes
 Cuando Angular evalúa una expresión
 primero mira en el scope asociado al elemento
 Si no lo encuentra va mirando en los scopes padres
 El último es el $rootScope
 https://docs.angularjs.org/guide/scope#scope-hierarchies
6
Herencia en controladores
 Si apilamos controladores en el HTML
 Cada directiva ng-controller crea un $scope hijo
 Por lo que se crea una jerarquía de scopes
 En la que cada uno hereda propiedades y métodos de los controllers que
se encuentran más “arriba”
7
<div class="spicy">
<div ng-controller="MainController">
<p>Good {{timeOfDay}}, {{name}}!</p>
<div ng-controller="ChildController">
<p>Good {{timeOfDay}}, {{name}}!</p>
<div ng-controller="GrandChildController">
<p>Good {{timeOfDay}}, {{name}}!</p>
</div>
</div>
</div>
</div>
Ciclo de vida del $scope
 Creación
 Del scope raíz y de los hijos
 Registro de watchers
 Por parte de las directivas
 Mutado del modelo
 Como resultado del two-way data binding
 Observación del mutado
 Propagación por los scopes hijos y observación de posibles cambios
 Destrucción
 Cuando ya no es necesario
8
Directivas personalizadas
 Además de las directivas incluidas en el núcleo de Angular
 Pueden crearse directivas personalizadas
 Hay diferentes tipos
 Directivas que extienden un template
 Directivas que manipulan el DOM
 Directivas que recubren otros elementos
 Directivas que añaden Event Listeners
 Directivas que se comunican entre sí
 Se crean con la función de módulo module.directive
9
Directivas personalizadas
10
angular.module('docsSimpleDirective', [])
.controller('Controller', ['$scope', function($scope) {
$scope.customer = {
name: 'Naomi',
address: '1600 Amphitheatre'
};
}])
.directive('myCustomer', function() {
return {
template: 'Name: {{customer.name}} Address: {{customer.address}}'
};
});
<div ng-controller="Controller">
<div my-customer></div>
</div>
Filtros personalizados
 Además de los filtros incluidos en Angular por defecto
 Pueden definirse filtros personalizados
 Mediante la función module.filter
 Esta función debe ser una función “pura”
 Siempre debe devolver le mismo resultado dados los mismos argumentos
 No debe afectar al estado externo de otros servicios
11
Filtros personalizados
12
angular.module('myReverseFilterApp', [])
.filter('reverse', function() {
return function(input, uppercase) {
input = input || '';
var out = '';
for (var i = 0; i < input.length; i++) {
out = input.charAt(i) + out;
}
// conditional based on optional argument
if (uppercase) {
out = out.toUpperCase();
}
return out;
};
})
.controller('MyController', ['$scope', 'reverseFilter', function($scope, reverseFilter) {
$scope.greeting = 'hello';
$scope.filteredGreeting = reverseFilter($scope.greeting);
}]);
Filtros personalizados
13
angular.module('myReverseFilterApp', [])
.filter('reverse', function() {
return function(input, uppercase) {
for (var i = 0; i < input.length; i++) {
out = input.charAt(i) + out;
}
if (uppercase) { // conditional based on optional argument
out = out.toUpperCase();
}
return out;
};
})
.controller('MyController', ['$scope’, function($scope) {
$scope.greeting = 'hello’;
}]);
<div ng-controller="MyController">
<input ng-model="greeting" type="text"><br>
Reverse: {{ greeting | reverse }}<br>
Reverse + uppercase: {{ greeting | reverse:true }}<br>
</div>
Validación de formularios personalizada
 Se hace definiendo nuevas directivas
14
var INTEGER_REGEXP = /^-?d+$/;
app.directive('integer', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$validators.integer = function(modelValue, viewValue) {
if (ctrl.$isEmpty(modelValue)) {
return true; // consider empty models to be valid
}
if (INTEGER_REGEXP.test(viewValue)) {
return true; // it is valid
}
return false; // it is invalid
};
}
};
});
Validación de formularios personalizada
15
<input type="number" ng-model="size" name="size” min="0" max="10" integer />
<span ng-show="form.size.$error.integer">The value is not a valid integer!</span>
Documentación
 Inicialización manual
 https://docs.angularjs.org/guide/bootstrap
 Herencia de controladores
 https://github.com/angular/angular.js/wiki/Understanding-Scopes
 Validación personalizada
 https://docs.angularjs.org/guide/forms#custom-validation
16
AngularJS
Temas avanzados
Álvaro Alonso

Curso AngularJS - 7. temas avanzados

  • 1.
  • 2.
    Inicialización manual  Angularse inicializa automáticamente cuando el DOM está cargado completamente  En ese momento busca la directiva ngApp y si la encuentra  Carga el módulo indicado por la directiva  Crea el inyector para la aplicación  Compila el DOM  Pero también se puede inicializar Angular de forma manual  Mediante angular.bootstrap(…) 2
  • 3.
    Inicialización manual 3 <!doctype html> <html> <body> <divng-controller="MyController"> Hello {{greetMe}}! </div> <script src="http://code.angularjs.org/snapshot/angular.js"></script> <script> angular.module('myApp', []) .controller('MyController', ['$scope', function ($scope) { $scope.greetMe = 'World'; }]); angular.element(document).ready(function() { angular.bootstrap(document, ['myApp']); }); </script> </body> </html>
  • 4.
    Dependency Injection  InlineArray Annotation (recomendada)  $inject Property Annotation  Implicit Annotation (no funciona con código minificado!!!) Formas alternativas 4 someModule.controller('MyController', ['$scope', 'greeter', function($scope, greeter) { // ... }]); var MyController = function($scope, greeter) { // ... } MyController.$inject = ['$scope', 'greeter']; someModule.controller('MyController', MyController); someModule.controller('MyController', function($scope, greeter) { // ... });
  • 5.
    Dependency Injection  Coninicialización automática  Con inicialización manual Evitar Implicit Annotation 5 <!doctype html> <html ng-app="myApp" ng-strict-di> <body> I can add: {{ 1 + 2 }}. <script src="angular.js"></script> </body> </html> angular.bootstrap(document, ['myApp'], { strictDi: true });
  • 6.
    Jerarquía de $scope Cada aplicación de angular tiene  Un único $rootScope  Varios $scope hijos  Cuando se crea un nuevo scope éste se añade como hijo de su scope padre  Así crea un árbol de scopes  Cuando Angular evalúa una expresión  primero mira en el scope asociado al elemento  Si no lo encuentra va mirando en los scopes padres  El último es el $rootScope  https://docs.angularjs.org/guide/scope#scope-hierarchies 6
  • 7.
    Herencia en controladores Si apilamos controladores en el HTML  Cada directiva ng-controller crea un $scope hijo  Por lo que se crea una jerarquía de scopes  En la que cada uno hereda propiedades y métodos de los controllers que se encuentran más “arriba” 7 <div class="spicy"> <div ng-controller="MainController"> <p>Good {{timeOfDay}}, {{name}}!</p> <div ng-controller="ChildController"> <p>Good {{timeOfDay}}, {{name}}!</p> <div ng-controller="GrandChildController"> <p>Good {{timeOfDay}}, {{name}}!</p> </div> </div> </div> </div>
  • 8.
    Ciclo de vidadel $scope  Creación  Del scope raíz y de los hijos  Registro de watchers  Por parte de las directivas  Mutado del modelo  Como resultado del two-way data binding  Observación del mutado  Propagación por los scopes hijos y observación de posibles cambios  Destrucción  Cuando ya no es necesario 8
  • 9.
    Directivas personalizadas  Ademásde las directivas incluidas en el núcleo de Angular  Pueden crearse directivas personalizadas  Hay diferentes tipos  Directivas que extienden un template  Directivas que manipulan el DOM  Directivas que recubren otros elementos  Directivas que añaden Event Listeners  Directivas que se comunican entre sí  Se crean con la función de módulo module.directive 9
  • 10.
    Directivas personalizadas 10 angular.module('docsSimpleDirective', []) .controller('Controller',['$scope', function($scope) { $scope.customer = { name: 'Naomi', address: '1600 Amphitheatre' }; }]) .directive('myCustomer', function() { return { template: 'Name: {{customer.name}} Address: {{customer.address}}' }; }); <div ng-controller="Controller"> <div my-customer></div> </div>
  • 11.
    Filtros personalizados  Ademásde los filtros incluidos en Angular por defecto  Pueden definirse filtros personalizados  Mediante la función module.filter  Esta función debe ser una función “pura”  Siempre debe devolver le mismo resultado dados los mismos argumentos  No debe afectar al estado externo de otros servicios 11
  • 12.
    Filtros personalizados 12 angular.module('myReverseFilterApp', []) .filter('reverse',function() { return function(input, uppercase) { input = input || ''; var out = ''; for (var i = 0; i < input.length; i++) { out = input.charAt(i) + out; } // conditional based on optional argument if (uppercase) { out = out.toUpperCase(); } return out; }; }) .controller('MyController', ['$scope', 'reverseFilter', function($scope, reverseFilter) { $scope.greeting = 'hello'; $scope.filteredGreeting = reverseFilter($scope.greeting); }]);
  • 13.
    Filtros personalizados 13 angular.module('myReverseFilterApp', []) .filter('reverse',function() { return function(input, uppercase) { for (var i = 0; i < input.length; i++) { out = input.charAt(i) + out; } if (uppercase) { // conditional based on optional argument out = out.toUpperCase(); } return out; }; }) .controller('MyController', ['$scope’, function($scope) { $scope.greeting = 'hello’; }]); <div ng-controller="MyController"> <input ng-model="greeting" type="text"><br> Reverse: {{ greeting | reverse }}<br> Reverse + uppercase: {{ greeting | reverse:true }}<br> </div>
  • 14.
    Validación de formulariospersonalizada  Se hace definiendo nuevas directivas 14 var INTEGER_REGEXP = /^-?d+$/; app.directive('integer', function() { return { require: 'ngModel', link: function(scope, elm, attrs, ctrl) { ctrl.$validators.integer = function(modelValue, viewValue) { if (ctrl.$isEmpty(modelValue)) { return true; // consider empty models to be valid } if (INTEGER_REGEXP.test(viewValue)) { return true; // it is valid } return false; // it is invalid }; } }; });
  • 15.
    Validación de formulariospersonalizada 15 <input type="number" ng-model="size" name="size” min="0" max="10" integer /> <span ng-show="form.size.$error.integer">The value is not a valid integer!</span>
  • 16.
    Documentación  Inicialización manual https://docs.angularjs.org/guide/bootstrap  Herencia de controladores  https://github.com/angular/angular.js/wiki/Understanding-Scopes  Validación personalizada  https://docs.angularjs.org/guide/forms#custom-validation 16
  • 17.