Angularjs Es
Angularjs Es
Angularjs Es
#angularjs
Tabla de contenido
Acerca de 1
Observaciones 2
Versiones 2
Examples 9
Empezando 9
ng-app 14
Directivas 14
Minificación en Angular 15
Observaciones 19
Examples 19
¿Cómo puede limitar el alcance de una directiva y por qué haría esto? 23
Examples 25
En el controlador: 25
Introducción 27
Examples 27
Angularjs muestra datos con filtro, paginación 27
Examples 28
Ejemplo 28
Observaciones 35
Examples 35
Uso 35
UI-Router: 36
ngRuta: 36
Utilizando la directiva 37
Observaciones 38
Examples 38
Observaciones 41
Examples 41
Capítulo 9: Componentes 43
Parámetros 43
Observaciones 44
Examples 44
Componentes en angular JS 46
Observaciones 48
Examples 48
Casos de uso 48
Sintaxis 51
Examples 51
Su primer controlador 51
Creando Controladores 53
Controladores anidados 56
Examples 57
Controlador 57
Sintaxis 58
Observaciones 58
Examples 58
Decorar directiva 59
Decorar filtro 60
Examples 67
1. cuerda 67
2. Objeto 67
3. Array 68
Examples 69
ngRepetir 69
ngShow y ngOcultar 73
ngOpciones 74
ngModel 76
clase ng 77
ngIf 77
JavaScript 78
Ver 78
Promesa de la función 79
ngMouseenter y ngMouseleave 79
deshabilitado 80
ngDblclick 80
Haga clic en 82
ngRequisito 83
ng-model-options 83
capa ng 84
ngIncluir 84
ngSrc 85
ngPatrón 85
ngValue 86
ngCopy 86
ngPaste 86
ngHref 87
ngList 87
Introducción 89
Parámetros 89
Examples 91
Directivo decorador 98
Examples 101
Introducción 107
Examples 107
Examples 109
Observaciones 115
Examples 115
Introducción 120
Sintaxis 120
Examples 120
Parámetros 121
Examples 121
Sintaxis: 122
Siempre cancele el registro de $ rootScope. $ En los escuchas en el evento scope $ destory 125
Examples 126
Javascript 126
HTML 127
Examples 131
example.js 131
example.html 131
Examples 133
Examples 135
angular.equals 135
angular.isString 135
angular.isArray 136
angular.merge 136
angular.isfecha 137
angular.isNumber 137
angular.isFunción 138
angular.toJson 138
angular.fromJson 139
angular.noop 139
angular.isObjeto 140
angular.iselemento 140
angular.copy 140
Observaciones 143
Examples 143
Introducción 145
Examples 145
Empezando 145
Sintaxis 149
Observaciones 149
Examples 149
Inyecciones 149
Introducción 152
Examples 152
Examples 156
Módulos 156
Módulos 156
Introducción 158
Examples 158
Introducción 159
Sintaxis 159
Parámetros 159
Observaciones 159
Examples 159
Introducción 162
Examples 162
ng-view 162
Capítulo 36: Opciones de enlaces AngularJS (`=`, `@`, `&` etc.) 164
Observaciones 164
Examples 164
Examples 167
Examples 169
4 observadores 171
Vigilantes 174
ng-si 176
ng-show 177
Ejemplo 177
Conclusión 177
Siempre anular el registro de los oyentes registrados en otros ámbitos distintos del alcan 178
Examples 179
Examples 183
Propiedades 186
Sintaxis 190
Observaciones 190
Examples 190
Constante 190
Valor 191
Fábrica 191
Servicio 192
Proveedor 192
Examples 194
Observaciones 197
Examples 197
Sintaxis 202
Examples 202
Examples 206
Examples 208
Introducción 215
Examples 215
Examples 219
Examples 223
Ejecutar la aplicación localmente 223
Sintaxis 226
Examples 226
Examples 231
Examples 233
ngMessages 235
Ejemplo 235
Creditos 238
Acerca de
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: angularjs
It is an unofficial and free AngularJS ebook created for educational purposes. All the content is
extracted from Stack Overflow Documentation, which is written by many hardworking individuals at
Stack Overflow. It is neither affiliated with Stack Overflow nor official AngularJS.
The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.
Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to [email protected]
https://riptutorial.com/es/home 1
Capítulo 1: Empezando con AngularJS
Observaciones
AngularJS es un marco de aplicación web diseñado para simplificar el desarrollo de aplicaciones
del lado del cliente enriquecido. Esta documentación es para Angular 1.x , el antecesor de la
versión más moderna de Angular 2 o consulte la documentación de Stack Overflow para Angular
2.
Versiones
1.6.5 2017-07-03
1.6.4 2017-03-31
1.6.3 2017-03-08
1.6.2 2017-02-07
1.5.11 2017-01-13
1.6.1 2016-12-23
1.5.10 2016-12-15
1.6.0 2016-12-08
1.6.0-rc.2 2016-11-24
1.5.9 2016-11-24
1.6.0-rc.1 2016-11-21
1.6.0-rc.0 2016-10-26
1.2.32 2016-10-11
1.4.13 2016-10-10
1.2.31 2016-10-10
1.5.8 2016-07-22
1.2.30 2016-07-21
1.5.7 2016-06-15
https://riptutorial.com/es/home 2
Versión Fecha de lanzamiento
1.4.12 2016-06-15
1.5.6 2016-05-27
1.4.11 2016-05-27
1.5.5 2016-04-18
1.5.4 2016-04-14
1.5.3 2016-03-25
1.5.2 2016-03-19
1.4.10 2016-03-16
1.5.1 2016-03-16
1.5.0 2016-02-05
1.5.0-rc.2 2016-01-28
1.4.9 2016-01-21
1.5.0-rc.1 2016-01-16
1.5.0-rc.0 2015-12-09
1.4.8 2015-11-20
1.5.0-beta.2 2015-11-18
1.4.7 2015-09-30
1.3.20 2015-09-30
1.2.29 2015-09-30
1.5.0-beta.1 2015-09-30
1.5.0-beta.0 2015-09-17
1.4.6 2015-09-17
1.3.19 2015-09-17
1.4.5 2015-08-28
1.3.18 2015-08-19
https://riptutorial.com/es/home 3
Versión Fecha de lanzamiento
1.4.4 2015-08-13
1.4.3 2015-07-15
1.3.17 2015-07-07
1.4.2 2015-07-07
1.4.1 2015-06-16
1.3.16 2015-06-06
1.4.0 2015-05-27
1.4.0-rc.2 2015-05-12
1.4.0-rc.1 2015-04-24
1.4.0-rc.0 2015-04-10
1.3.15 2015-03-17
1.4.0-beta.6 2015-03-17
1.4.0-beta.5 2015-02-24
1.3.14 2015-02-24
1.4.0-beta.4 2015-02-09
1.3.13 2015-02-09
1.3.12 2015-02-03
1.4.0-beta.3 2015-02-03
1.3.11 2015-01-27
1.4.0-beta.2 2015-01-27
1.4.0-beta.1 2015-01-20
1.3.10 2015-01-20
1.3.9 2015-01-15
1.4.0-beta.0 2015-01-14
1.3.8 2014-12-19
https://riptutorial.com/es/home 4
Versión Fecha de lanzamiento
1.2.28 2014-12-16
1.3.7 2014-12-15
1.3.6 2014-12-09
1.3.5 2014-12-02
1.3.4 2014-11-25
1.2.27 2014-11-21
1.3.3 2014-11-18
1.3.2 2014-11-07
1.3.1 2014-10-31
1.3.0 2014-10-14
1.3.0-rc.5 2014-10-09
1.2.26 2014-10-03
1.3.0-rc.4 2014-10-02
1.3.0-rc.3 2014-09-24
1.2.25 2014-09-17
1.3.0-rc.2 2014-09-17
1.2.24 2014-09-10
1.3.0-rc.1 2014-09-10
1.3.0-rc.0 2014-08-30
1.2.23 2014-08-23
1.3.0-beta.19 2014-08-23
1.2.22 2014-08-12
1.3.0-beta.18 2014-08-12
1.2.21 2014-07-25
1.3.0-beta.17 2014-07-25
https://riptutorial.com/es/home 5
Versión Fecha de lanzamiento
1.3.0-beta.16 2014-07-18
1.2.20 2014-07-11
1.3.0-beta.15 2014-07-11
1.2.19 2014-07-01
1.3.0-beta.14 2014-07-01
1.3.0-beta.13 2014-06-16
1.3.0-beta.12 2014-06-14
1.2.18 2014-06-14
1.3.0-beta.11 2014-06-06
1.2.17 2014-06-06
1.3.0-beta.10 2014-05-24
1.3.0-beta.9 2014-05-17
1.3.0-beta.8 2014-05-09
1.3.0-beta.7 2014-04-26
1.3.0-beta.6 2014-04-22
1.2.16 2014-04-04
1.3.0-beta.5 2014-04-04
1.3.0-beta.4 2014-03-28
1.2.15 2014-03-22
1.3.0-beta.3 2014-03-21
1.3.0-beta.2 2014-03-15
1.3.0-beta.1 2014-03-08
1.2.14 2014-03-01
1.2.13 2014-02-15
1.2.12 2014-02-08
https://riptutorial.com/es/home 6
Versión Fecha de lanzamiento
1.2.11 2014-02-03
1.2.10 2014-01-25
1.2.9 2014-01-15
1.2.8 2014-01-10
1.2.7 2014-01-03
1.2.6 2013-12-20
1.2.5 2013-12-13
1.2.4 2013-12-06
1.2.3 2013-11-27
1.2.2 2013-11-22
1.2.1 2013-11-15
1.2.0 2013-11-08
1.2.0-rc.3 2013-10-14
1.2.0-rc.2 2013-09-04
1.0.8 2013-08-22
1.2.0rc1 2013-08-13
1.0.7 2013-05-22
1.1.5 2013-05-22
1.0.6 2013-04-04
1.1.4 2013-04-04
1.0.5 2013-02-20
1.1.3 2013-02-20
1.0.4 2013-01-23
1.1.2 2013-01-23
1.1.1 2012-11-27
https://riptutorial.com/es/home 7
Versión Fecha de lanzamiento
1.0.3 2012-11-27
1.1.0 2012-09-04
1.0.2 2012-09-04
1.0.1 2012-06-25
1.0.0 2012-06-14
v1.0.0rc12 2012-06-12
v1.0.0rc11 2012-06-11
v1.0.0rc10 2012-05-24
v1.0.0rc9 2012-05-15
v1.0.0rc8 2012-05-07
v1.0.0rc7 2012-05-01
v1.0.0rc6 2012-04-21
v1.0.0rc5 2012-04-12
v1.0.0rc4 2012-04-05
v1.0.0rc3 2012-03-30
v1.0.0rc2 2012-03-21
g3-v1.0.0rc1 2012-03-14
g3-v1.0.0-rc2 2012-03-16
1.0.0rc1 2012-03-14
0.10.6 2012-01-17
0.10.5 2011-11-08
0.10.4 2011-10-23
0.10.3 2011-10-14
0.10.2 2011-10-08
0.10.1 2011-09-09
https://riptutorial.com/es/home 8
Versión Fecha de lanzamiento
0.10.0 2011-09-02
0.9.19 2011-08-21
0.9.18 2011-07-30
0.9.17 2011-06-30
0.9.16 2011-06-08
0.9.15 2011-04-12
0.9.14 2011-04-01
0.9.13 2011-03-14
0.9.12 2011-03-04
0.9.11 2011-02-09
0.9.10 2011-01-27
0.9.9 2011-01-14
0.9.7 2010-12-11
0.9.6 2010-12-07
0.9.5 2010-11-25
0.9.4 2010-11-19
0.9.3 2010-11-11
0.9.2 2010-11-03
0.9.1 2010-10-27
0.9.0 2010-10-21
Examples
Empezando
<!DOCTYPE html>
<html ng-app>
https://riptutorial.com/es/home 9
<head>
<title>Hello, Angular</title>
<script src="https://code.angularjs.org/1.5.8/angular.min.js"></script>
</head>
<body ng-init="name='World'">
<label>Name</label>
<input ng-model="name" />
<span>Hello, {{ name }}!</span>
<p ng-bind="name"></p>
</body>
</html>
Demo en vivo
Cuando abra el archivo con un navegador, verá un campo de entrada seguido del texto Hello,
World! . La edición del valor en la entrada actualizará el texto en tiempo real, sin la necesidad de
actualizar toda la página.
Explicación:
<script src="https://code.angularjs.org/1.5.8/angular.min.js"></script>
2. Defina el documento HTML como una aplicación Angular con la directiva ng-app
<html ng-app>
Tenga en cuenta que ng-init debe utilizarse únicamente con fines demostrativos y de
prueba. Al crear una aplicación real, los controladores deben inicializar los datos.
4. Enlazar datos del modelo a la vista en controles HTML. Enlazar una <input> a la propiedad
de name con ng-model
6. Otra forma de enlazar la propiedad de name es usar ng-bind lugar de manillares "{{ }}"
<span ng-bind="name"></span>
Los últimos tres pasos establecen el enlace de datos de dos vías . Los cambios realizados en la
https://riptutorial.com/es/home 10
entrada actualizan el modelo , que se refleja en la vista .
Hay una diferencia entre usar manillares y ng-bind . Si usa manillares, puede ver el Hello,
{{name}} real Hello, {{name}} medida que se carga la página antes de que se resuelva la
expresión (antes de que se carguen los datos), mientras que si usa ng-bind , solo mostrará los
datos cuando el nombre esta resuelto. Como alternativa, se puede utilizar la directiva ng-cloak
para evitar que se muestren los manillares antes de compilarlos.
<!DOCTYPE html>
<html ng-app="myDemoApp">
<head>
<style>.started { background: gold; }</style>
<script src="https://code.angularjs.org/1.5.8/angular.min.js"></script>
<script>
function MyDataService() {
return {
getWorlds: function getWorlds() {
return ["this world", "another world"];
}
};
}
function DemoController(worldsService) {
var vm = this;
vm.messages = worldsService.getWorlds().map(function(w) {
return "Hello, " + w + "!";
});
}
https://riptutorial.com/es/home 11
Demo en vivo
3. angular.module(...) utilizado con una matriz como segundo argumento crea un nuevo
módulo. Esta matriz se utiliza para proporcionar una lista de dependencias de módulo. En
este ejemplo, encadenamos llamadas sobre el resultado de la función del module(...) ;
6. .config(...) Utilice este método para registrar el trabajo que debe realizarse en la carga del
módulo.
7. .run(...) se asegura de que el código se ejecute en el momento del inicio y tome una matriz
de elementos como parámetro. Utilice este método para registrar el trabajo que se debe
realizar cuando el inyector haya terminado de cargar todos los módulos.
• el primer elemento es hacerle saber a Angular que la función de startup requiere que
el servicio $rootScope se inyecte como un argumento;
• el segundo elemento es permitir que Angular sepa que la función de startup requiere
que el servicio integrado de $window se inyecte como un argumento;
• el último elemento de la matriz, startup , es la función real para ejecutar en el inicio;
8. ng-class es la directiva ngClass para establecer una class dinámica, y en este ejemplo utiliza
hasStarted en $rootScope dinámicamente
9. ng-cloak es una directiva para evitar que la plantilla html de Angular no procesada (por
ejemplo, " {{ msg }} ") se muestre brevemente antes de que Angular haya cargado
completamente la aplicación.
10. ng-controller es la directiva que le pide a Angular que cree una instancia de un nuevo
controlador con un nombre específico para orquestar esa parte del DOM;
11. ng-repeat es la directiva para hacer una iteración angular sobre una colección y clonar una
plantilla DOM para cada elemento;
12. {{ msg }} muestra la interpolación : la representación en el lugar de una parte del alcance o
controlador;
Como Angular usa HTML para extender una página web y Javascript simple para agregar lógica,
facilita la creación de una página web usando ng-app , ng-controller y algunas directivas
https://riptutorial.com/es/home 12
integradas como ng-if , ng-repeat , etc. Con la nueva sintaxis del controlador , los usuarios
nuevos de Angular pueden adjuntar funciones y datos a su controlador en lugar de usar $scope .
Sin embargo, tarde o temprano, es importante entender qué es exactamente este asunto del
$scope . Seguirá apareciendo en ejemplos, por lo que es importante tener un poco de
comprensión.
<div ng-app="myApp">
<h1>Hello {{ name }}</h1>
</div>
La respuesta es que Angular crea un objeto $rootScope . Esto es simplemente un objeto Javascript
normal y, por lo tanto, name es una propiedad en el objeto $rootScope :
angular.module("myApp", [])
.run(function($rootScope) {
$rootScope.name = "World!";
});
Y al igual que con el alcance global en Javascript, generalmente no es una buena idea agregar
elementos al alcance global o $rootScope .
Por supuesto, la mayoría de las veces, creamos un controlador y ponemos nuestra funcionalidad
requerida en ese controlador. Pero cuando creamos un controlador, Angular hace magia y crea
un objeto $scope para ese controlador. Esto se refiere a veces como el alcance local .
<div ng-app="myApp">
<div ng-controller="MyController">
<h1>Hello {{ name }}</h1>
</div>
</div>
permitiría que se pueda acceder al ámbito local a través del parámetro $scope .
angular.module("myApp", [])
.controller("MyController", function($scope) {
$scope.name = "Mr Local!";
});
Un controlador sin un parámetro de $scope puede simplemente no necesitarlo por alguna razón.
Pero es importante darse cuenta de que, incluso con la sintaxis de controllerAs , el alcance
local existe.
https://riptutorial.com/es/home 13
Dado que $scope es un objeto de JavaScript, Angular lo configura mágicamente para heredarlo
prototípicamente de $rootScope . Y como puedes imaginar, puede haber una cadena de ámbitos.
Por ejemplo, podría crear un modelo en un controlador principal y adjuntarlo al alcance del
controlador principal como $scope.model .
Nada de esto es inicialmente evidente, ya que solo es Angular haciendo su magia de fondo. Pero
comprender el $scope es un paso importante para conocer cómo funciona Angular.
Angular 1 es en el fondo un compilador DOM. Podemos pasarlo en HTML, ya sea como una
plantilla o simplemente como una página web normal, y luego hacer que compile una aplicación.
Podemos decirle a Angular que trate una región de la página como una expresión usando la
sintaxis de estilo de manillares {{ }} . Cualquier cosa entre las llaves se compilará, así:
{{ 'Hello' + 'World' }}
HelloWorld
ng-app
Le decimos a Angular qué parte de nuestro DOM debe tratar como la plantilla maestra usando la
directiva ng-app . Una directiva es un atributo o elemento personalizado con el que el compilador
de plantillas angulares sabe cómo tratar. Agreguemos una directiva ng-app ahora:
<html>
<head>
<script src="/angular.js"></script>
</head>
<body ng-app>
{{ 'Hello' + 'World' }}
</body>
</html>
Ahora le he dicho al elemento del cuerpo que sea la plantilla raíz. Cualquier cosa en él será
compilada.
Directivas
Las directivas son directivas de compilación. Extienden las capacidades del compilador Angular
DOM. Por eso Misko , el creador de Angular, describe a Angular como:
https://riptutorial.com/es/home 14
"Lo que habría sido un navegador web si se hubiera construido para aplicaciones web.
Literalmente creamos nuevos atributos y elementos HTML, y hacemos que Angular los compile
en una aplicación. ng-app es una directiva que simplemente enciende el compilador. Otras
directivas incluyen:
Angular viene con alrededor de 100 directivas integradas que le permiten realizar las tareas más
comunes. También podemos escribir el nuestro, y estos serán tratados de la misma manera que
las directivas integradas.
Construimos una aplicación Angular a partir de una serie de directivas, conectadas con HTML.
Minificación en Angular
¿Qué es la minificación?
Es el proceso de eliminar todos los caracteres innecesarios del código fuente sin cambiar su
funcionalidad.
Sintaxis normal
Si usamos la sintaxis angular normal para escribir un controlador, luego de minimizar nuestros
archivos, se romperá nuestra funcionalidad.
var app=angular.module("mainApp",[]);app.controller("FirstController",function(e){e.name=
'Hello World !'})
Aquí, la minificación eliminó los espacios innecesarios y la variable $ scope del código. Entonces,
cuando usamos este código minificado, no se imprimirá nada a la vista. Porque $ scope es una
parte crucial entre el controlador y la vista, que ahora es reemplazada por la pequeña variable 'e'.
Por lo tanto, cuando ejecute la aplicación, se producirá un error de dependencia de Unknown
Provider 'e'.
Hay dos formas de anotar su código con información de nombre de servicio que son seguras de
minificación:
https://riptutorial.com/es/home 15
var app = angular.module('mainApp', []);
app.controller('FirstController', ['$scope', function($scope) {
$scope.message = 'Hello World !';
}]);
FirstController.$inject = ['$scope'];
var FirstController = function($scope) {
$scope.message = 'Hello World !';
}
var
app=angular.module("mainApp",[]);app.controller("FirstController",["$scope",function(a){a.message="Hell
World !"}]);
Aquí, angular considerará la variable 'a' para ser tratada como $ scope, y mostrará la salida como
'Hello World!'.
https://riptutorial.com/es/home 16
• https://egghead.io/courses/angularjs-app-from-scratch-getting-started
https://riptutorial.com/es/home 17
• https://egghead.io/courses/angularjs-application-architecture
• https://egghead.io/courses/angular-material-introduction
• https://egghead.io/courses/building-an-angular-1-x-ionic-application
• https://egghead.io/courses/angular-and-webpack-for-modular-applications
• https://egghead.io/courses/angularjs-authentication-with-jwt
• https://egghead.io/courses/angularjs-data-modeling
• https://egghead.io/courses/angular-automation-with-gulp
• https://egghead.io/courses/learn-protractor-testing-for-angularjs
• https://egghead.io/courses/ionic-quickstart-for-windows
• https://egghead.io/courses/build-angular-1-x-apps-with-redux
• https://egghead.io/courses/using-angular-2-patterns-in-angular-1-x-apps
https://riptutorial.com/es/home 18
Capítulo 2: Alcances $ angulares
Observaciones
Angular usa un árbol de ámbitos para vincular la lógica (desde controladores, directivas, etc.) a la
vista y es el mecanismo principal detrás de la detección de cambios en AngularJS. Se puede
encontrar una referencia más detallada para los ámbitos en docs.angularjs.org
La raíz del árbol es accesible a través del servicio inyectable $ rootScope . Todos los ámbitos
de $ child heredan los métodos y las propiedades de su alcance de $ padre, permitiendo a los
niños acceder a métodos sin el uso de los Servicios Angulares.
Examples
Ejemplo básico de la herencia $ scope
angular.module('app', [])
.controller('myController', ['$scope', function($scope){
$scope.person = { name: 'John Doe' };
}]);
En este ejemplo, la directiva ng-repeat crea un nuevo ámbito para cada uno de sus hijos recién
creados.
Estos ámbitos creados son secundarios de su ámbito principal (en este caso, el ámbito creado
por myController) y, por lo tanto, heredan todas sus propiedades, como persona.
En javascript, la asignación de un valor no primitivo (como Objeto, Array, Función y muchos más)
mantiene una referencia (una dirección en la memoria) al valor asignado.
Asignar un valor primitivo (Cadena, Número, Booleano o Símbolo) a dos variables diferentes, y
cambiar una, no cambiará ambas:
var x = 5;
var y = x;
y = 6;
console.log(y === x, x, y); //false, 5, 6
Pero con un valor que no es primitiva, ya que ambas variables son simplemente mantener las
https://riptutorial.com/es/home 19
referencias al mismo objeto, el cambio de una variable va a cambiar a la otra:
En angular, cuando se crea un ámbito, se le asignan todas sus propiedades principales. Sin
embargo, cambiar las propiedades después solo afectará al ámbito principal si no es un valor
primitivo:
angular.module('app', [])
.controller('myController', ['$scope', function($scope){
$scope.person = { name: 'John Doe' }; //non-primitive
$scope.name = 'Jhon Doe'; //primitive
}])
.controller('myController1', ['$scope', function($scope){}]);
Recuerde: en Angular, los ámbitos se pueden crear de muchas maneras (como directivas
incorporadas o personalizadas, o la función $scope.$new() ), y es probable que sea imposible
mantener un registro del árbol de ámbitos.
Utilizar solo valores no primitivos como propiedades de alcance lo mantendrá en el lado seguro (a
menos que necesite una propiedad para no heredar, u otros casos en los que tenga conocimiento
de la herencia de alcance).
Tenga cuidado, este enfoque podría considerarse como un mal diseño para las aplicaciones
angulares, ya que requiere que los programadores recuerden dónde se ubican las funciones en el
árbol de alcance y que sean conscientes de la herencia del alcance. En muchos casos, se
preferiría inyectar un servicio ( práctica angular: uso de la herencia del alcance frente a la
inyección .
Este ejemplo solo muestra cómo se puede usar la herencia de alcance para nuestras
necesidades y cómo puede aprovecharla, y no las mejores prácticas para diseñar una aplicación
completa.
En algunos casos, podríamos aprovechar la herencia del alcance y establecer una función como
una propiedad del rootScope. De esta manera, todos los ámbitos de la aplicación (excepto los
ámbitos aislados) heredarán esta función, y se puede llamar desde cualquier parte de la
aplicación.
https://riptutorial.com/es/home 20
angular.module('app', [])
.run(['$rootScope', function($rootScope){
var messages = []
$rootScope.addMessage = function(msg){
messages.push(msg);
}
}]);
<div ng-app="app">
<a ng-click="addMessage('hello world!')">it could be accsessed from here</a>
<div ng-include="inner.html"></div>
</div>
inner.html:
<div>
<button ng-click="addMessage('page')">and from here to!</button>
</div>
Al igual que los elementos HTML normales, es posible que $ scopes tengan sus propios eventos.
Los eventos de $ scope se pueden suscribir de la siguiente manera:
Hay dos formas de activar su propio evento $ scope $ broadcast y $ emit . Para notificar a los
padres sobre el alcance de un evento específico, use $ emit
El ejemplo anterior activará los escuchas de eventos para my-event en el ámbito principal y
continuará subiendo el árbol de ámbitos a $ rootScope a menos que un oyente llame a
stopPropagation en el evento. Solo los eventos activados con $ stopPropagation pueden llamar
stopPropagation
El reverso de $ emit es $ broadcast , que activará a los oyentes de eventos en todos los ámbitos
secundarios del árbol de ámbitos que sean secundarios del alcance que se denominó $
broadcast .
https://riptutorial.com/es/home 21
Los eventos activados con $ broadcast no pueden ser cancelados.
Si bien la declaración de una función en $ rootscope tiene sus ventajas, también podemos
declarar una función $ scope en cualquier parte del código inyectado por el servicio $ scope.
Controlador, por ejemplo.
Controlador
$scope.myfunction();
<div ng-controller="myController">
<button ng-click="myFunction()"> Click me! </button>
</div>
Directiva
myApp.directive('triggerFunction', function() {
return {
scope: {
triggerFunction: '&'
},
link: function(scope, element) {
element.bind('mouseover', function() {
scope.triggerFunction();
});
}
};
});
<div ng-controller="myController">
<button trigger-function="myFunction()"> Hover over me! </button>
</div>
Por supuesto, puede usar ngMouseover para la misma cosa, pero lo especial de las directivas es
que puede personalizarlas de la manera que desee. Y ahora sabes cómo usar tus funciones de $
scope dentro de ellas, ¡sé creativo!
https://riptutorial.com/es/home 22
¿Cómo puede limitar el alcance de una directiva y por qué haría esto?
El alcance se utiliza como el "pegamento" que usamos para comunicarnos entre el controlador
principal, la directiva y la plantilla de la directiva. Cada vez que se arranca la aplicación
AngularJS, se crea un objeto rootScope. Cada ámbito creado por los controladores, directivas y
servicios se hereda de forma prototípica de rootScope.
Sí, podemos limitar el alcance de una directiva. Podemos hacerlo creando un ámbito aislado para
la directiva.
Directivas con el nuevo alcance aislado: cuando creamos un nuevo alcance aislado, no se
heredará del alcance principal. Este nuevo ámbito se denomina Ámbito aislado porque está
completamente separado de su ámbito principal. ¿Por qué? deberíamos usar un alcance aislado:
debemos usar un alcance aislado cuando queremos crear una directiva personalizada porque nos
aseguraremos de que nuestra directiva sea genérica y esté ubicada en cualquier lugar dentro de
la aplicación. El ámbito principal no va a interferir con el ámbito de la directiva.
app.controller("Ctrl1",function($scope){
$scope.name = "Prateek";
$scope.reverseName = function(){
$scope.name = $scope.name.split('').reverse().join('');
};
});
app.directive("myDirective", function(){
return {
restrict: "EA",
scope: {},
template: "<div>Your name is : {{name}}</div>"+
"Change your name : <input type='text' ng-model='name'/>"
};
});
Hay 3 tipos de prefijos que AngularJS proporciona para el alcance aislado estos son:
Todos estos prefijos reciben datos de los atributos del elemento directivo como:
<div my-directive
class="directive"
https://riptutorial.com/es/home 23
name="{{name}}"
reverse="reverseName()"
color="color" >
</div>
https://riptutorial.com/es/home 24
Capítulo 3: Almacenamiento de sesión
Examples
Manejo de la sesión de almacenamiento a través del servicio usando
angularjs.
'use strict';
/**
* @ngdoc factory
* @name app.factory:storageService
* @description This function will communicate with HTML5 sessionStorage via Factory Service.
*/
return {
get: function(key) {
return sessionStorage.getItem(key);
},
save: function(key, data) {
sessionStorage.setItem(key, data);
}
};
}]);
En el controlador:
Inyecte la dependencia de storageService en el controlador para establecer y obtener los datos
del almacenamiento de la sesión.
app.controller('myCtrl',['storageService',function(storageService) {
});
https://riptutorial.com/es/home 25
https://riptutorial.com/es/angularjs/topic/8201/almacenamiento-de-sesion
https://riptutorial.com/es/home 26
Capítulo 4: angularjs con filtro de datos,
paginación etc
Introducción
Ejemplo de proveedor y consulta sobre datos de visualización con filtro, paginación, etc. en
Angularjs.
Examples
Angularjs muestra datos con filtro, paginación
$scope.pageSize = 5;
$scope.dishes = [
'noodles',
'sausage',
'beans on toast',
'cheeseburger',
'battered mars bar',
'crisp butty',
'yorkshire pudding',
'wiener schnitzel',
'sauerkraut mit ei',
'salad',
'onion soup',
'bak choi',
'avacado maki'
];
https://riptutorial.com/es/home 27
Capítulo 5: AngularJS gotchas y trampas
Examples
El enlace de datos bidireccional deja de funcionar
Esto significa que cuando intenta vincular de forma bidireccional algunos datos a una primitiva
que se encuentra dentro de un ámbito secundario (o viceversa), es posible que las cosas no
funcionen como se espera. Aquí hay un ejemplo de lo fácil que es "romper" AngularJS.
1. Tener un "." Dentro de su plantilla HTML cada vez que enlace algunos datos
2. Utilice la sintaxis de controllerAs ya que promueve el uso de la vinculación a un objeto
"punteado"
3. $ parent se puede usar para acceder a las variables de scope principal en lugar de al alcance
secundario. como dentro de ng-if podemos usar ng-model="$parent.foo" ..
Una alternativa para lo anterior es vincular ngModel a una función getter / setter que actualizará la
versión en caché del modelo cuando se le llame con argumentos, o lo devolverá cuando se le
llame sin argumentos. Para utilizar una función getter / setter, debe agregar ng-model-options="{
getterSetter: true }" al elemento con el atributo ngModal , y llamar a la función getter si desea
mostrar su valor en la expresión ( Ejemplo de trabajo ).
Ejemplo
Ver:
https://riptutorial.com/es/home 28
Controlador:
var _foo = 'hello'; // this will be used to cache/represent the value of the 'foo' model
$scope.foo = function(val) {
// the function return the the internal '_foo' varibale when called with zero
arguments,
// and update the internal `_foo` when called with an argument
return arguments.length ? (_foo = val) : _foo;
};
}]);
Mejor práctica : es mejor mantener a los captadores rápidamente porque es probable que
Angular los llame con más frecuencia que otras partes de su código ( referencia ).
2. Es importante que la etiqueta base esté antes que cualquier etiqueta con solicitudes de URL.
De lo contrario, esto podría dar lugar a este error: "Resource interpreted as stylesheet but
transferred with MIME type text/html" . Por ejemplo:
<head>
<meta charset="utf-8">
<title>Job Seeker</title>
<base href="/">
3. Si no desea especificar una etiqueta base , configure $locationProvider para que no requiera
una etiqueta base pasando un objeto de definición con requireBase:false a
$locationProvider.html5Mode() como esto:
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
4. Para poder admitir la carga directa de URL de HTML5, debe habilitar la reescritura de URL
del lado del servidor. De AngularJS / Guía del desarrollador / Uso de $ location
https://riptutorial.com/es/home 29
aplicación (por ejemplo, index.html ). Requerir una etiqueta <base> también es
importante para este caso, ya que permite a Angular diferenciar entre la parte de
la URL que es la base de la aplicación y la ruta que debe ser manejada por la
aplicación.
RewriteEngine on
nginx
server {
server_name my-app;
root /path/to/app;
location / {
try_files $uri $uri/ /index.html;
}
}
Exprimir
A continuación se muestra la lista de algunos errores que los desarrolladores suelen cometer
durante el uso de las funcionalidades de AngularJS, algunas lecciones aprendidas y soluciones
para ellos.
https://riptutorial.com/es/home 30
1. Manipular el DOM a través del controlador.
Es legal, pero hay que evitarlo. Los controladores son los lugares donde define sus
dependencias, vincula sus datos a la vista y crea más lógica de negocios. Técnicamente puede
manipular el DOM en un controlador, pero siempre que necesite una manipulación similar o
similar en otra parte de su aplicación, se necesitará otro controlador. Por lo tanto, la mejor
práctica de este enfoque es crear una directiva que incluya todas las manipulaciones y usar la
directiva en toda su aplicación. Por lo tanto, el controlador deja la vista intacta y hace su trabajo.
En una directiva, la función de enlace es el mejor lugar para manipular el DOM. Tiene acceso
completo al alcance y al elemento, por lo que al usar una directiva, también puede aprovechar la
reutilización.
Puede acceder a los elementos DOM en la función de vinculación de varias maneras, como el
parámetro del element , el método angular.element() o el Javascript puro.
AngularJS es famoso por su enlace de datos de dos vías. Sin embargo, es posible que a veces
descubra que sus datos solo están enlazados en un solo sentido dentro de las directivas. Detente
ahí, AngularJS no está mal, pero probablemente tú. Las directivas son lugares poco peligrosos ya
que están involucrados los ámbitos de niños y los aislados. Supongamos que tiene la siguiente
directiva con una transclusión
<my-dir>
<my-transclusion>
</my-transclusion>
</my-dir>
Y dentro de mi-transclusión, tiene algunos elementos que están vinculados a los datos en el
ámbito externo.
<my-dir>
<my-transclusion>
<input ng-model="name">
</my-transclusion>
</my-dir>
$scope.data = {
name: 'someName'
}
https://riptutorial.com/es/home 31
Luego, en la transclusión, puede acceder a esta variable a través del objeto 'datos' y ver que el
enlace bidireccional funciona perfectamente.
<input ng-model="data.name">
No solo en las transclusiones, sino en toda la aplicación, es una buena idea usar la notación
punteada.
En realidad, es legal usar dos directivas juntas dentro del mismo elemento, siempre que cumpla
con la regla: no pueden existir dos ámbitos aislados en el mismo elemento. En general, al crear
una nueva directiva personalizada, asigna un ámbito aislado para facilitar el paso de parámetros.
Suponiendo que las directivas myDirA y myDirB tengan ámbitos aislados y myDirC no, el
siguiente elemento será válido:
Por lo tanto, las directivas deben usarse con prudencia, teniendo en cuenta los ámbitos.
$scope.$emit('someEvent', args);
$scope.$on('someEvent', function(){});
Hasta ahora todo parece perfecto. Pero recuerde que, si el controlador B aún no se ha invocado,
el evento no se detectará, lo que significa que se deben invocar los controladores de emisor y
receptor para que esto funcione. Entonces, una vez más, si no está seguro de que definitivamente
tiene que usar $ emit, construir un servicio parece una mejor manera.
$ scope. $ watch se usa para ver un cambio de variable. Cada vez que una variable ha cambiado,
este método es invocado. Sin embargo, un error común cometido es cambiar la variable dentro de
$ scope. $ Watch. Esto causará inconsistencias y un bucle infinito de digestión $ en algún punto.
$scope.$watch('myCtrl.myVariable', function(newVal) {
https://riptutorial.com/es/home 32
this.myVariable++;
});
Este es uno de los pecados más mortíferos. AngularJS tiene enlaces bidireccionales, y siempre
que algo cambia, las vistas se actualizan muchas veces. Entonces, si unes un método a un
atributo de una vista, ese método podría llamarse cientos de veces, lo que también te vuelve loco
durante la depuración. Sin embargo, solo hay algunos atributos que se crean para el enlace de
métodos, como ng-click, ng-blur, ng-on-change, etc., que esperan métodos como paremeter. Por
ejemplo, suponga que tiene la siguiente vista en su marca:
Aquí usted verifica el estado deshabilitado de la vista a través del método isDisabled. En el
controlador myCtrl, tienes:
vm.isDisabled = function(){
if(someCondition)
return true;
else
return false;
}
En teoría, puede parecer correcto, pero técnicamente esto causará una sobrecarga, ya que el
método se ejecutará innumerables veces. Para resolver esto, debes enlazar una variable. En su
controlador, la siguiente variable debe existir:
vm.isDisabled
if(someCondition)
vm.isDisabled = true
else
vm.isDisabled = false
Si la condición no es estable, puede vincular esto a otro evento. Entonces deberías enlazar esta
variable a la vista:
Ahora, todos los atributos de la vista tienen lo que esperan y los métodos se ejecutarán solo
cuando sea necesario.
https://riptutorial.com/es/home 33
AngularJS proporciona una gran comodidad con algunas de sus funcionalidades, no solo
simplificando su código sino que también lo hace más eficiente. Algunas de estas características
se enumeran a continuación:
1. angular.forEach para los bucles (Precaución, no puede "romperla"; solo puede evitar que
entre al cuerpo, así que considere el rendimiento aquí).
2. Elemento angular para selectores DOM
3. angular.copy : use esto cuando no debe modificar el objeto principal
4. Las validaciones de formularios ya son impresionantes. Utilice sucio, prístino, tocado,
válido, requerido y así sucesivamente.
5. Además del depurador Chrome, use la depuración remota para el desarrollo móvil
también.
6. Y asegúrate de usar Batarang . Es una extensión gratuita de Chrome donde puedes
inspeccionar fácilmente los ámbitos.
.
https://riptutorial.com/es/home 34
Capítulo 6: Carga lenta
Observaciones
1. Si sus dependencias cargadas perezosas requieren otras dependencias cargadas
perezosas, ¡asegúrese de cargarlas en el orden correcto!
angular.module('lazy', [
'alreadyLoadedDependency1',
'alreadyLoadedDependency2',
...
{
files: [
'path/to/lazily/loaded/dependency1.js',
'path/to/lazily/loaded/dependency2.js', //<--- requires lazily loaded dependency1
'path/to/lazily/loaded/dependency.css'
],
serie: true //Sequential load instead of parallel
}
]);
Examples
Preparando tu proyecto para carga lenta
//Make sure you put the correct dependency! it is spelled different than the service!
angular.module('app', [
'oc.lazyLoad',
'ui-router'
])
Uso
Para cargar archivos con $ocLazyLoad inyecte el servicio $ocLazyLoad en un controlador u otro
servicio
.controller('someCtrl', function($ocLazyLoad) {
$ocLazyLoad.load('path/to/file.js').then(...);
});
Otra variación:
$ocLazyLoad.load([
'bower_components/bootstrap/dist/js/bootstrap.js',
https://riptutorial.com/es/home 35
'bower_components/bootstrap/dist/css/bootstrap.css',
'partials/template1.html'
]);
UI-Router:
.state('profile', {
url: '/profile',
controller: 'profileCtrl as vm'
resolve: {
module: function($ocLazyLoad) {
return $ocLazyLoad.load([
'path/to/profile/module.js',
'path/to/profile/style.css'
]);
}
}
});
ngRuta:
.when('/profile', {
controller: 'profileCtrl as vm'
resolve: {
module: function($ocLazyLoad) {
return $ocLazyLoad.load([
'path/to/profile/module.js',
'path/to/profile/style.css'
]);
}
}
});
//lazy_module.js
angular.module('lazy', [
'alreadyLoadedDependency1',
'alreadyLoadedDependency2',
...
[
'path/to/lazily/loaded/dependency.js',
'path/to/lazily/loaded/dependency.css'
]
]);
https://riptutorial.com/es/home 36
Nota : ¡esta sintaxis solo funcionará para módulos cargados perezosamente!
Utilizando la directiva
<div oc-lazy-load="['path/to/lazy/loaded/directive.js',
'path/to/lazy/loaded/directive.html']">
</div>
https://riptutorial.com/es/home 37
Capítulo 7: Cómo funciona el enlace de datos
Observaciones
Entonces, si bien este concepto de enlace de datos en su conjunto es fácil para el desarrollador,
es bastante pesado en el navegador, ya que Angular escucha cada cambio de evento y ejecuta el
Ciclo de resumen. Debido a esto, siempre que adjuntemos algún modelo a la vista, asegúrese de
que Scope esté lo más optimizado posible.
Examples
Ejemplo de enlace de datos
<p ng-bind="message"></p>
No hay una verificación periódica de Ámbito si hay algún cambio en los Objetos adjuntos. No
todos los objetos adjuntos al alcance son observados. El alcance prototípicamente mantiene un
$$ WatchersArray . El alcance solo se repite a través de WatchersArray cuando se llama $
digest.
https://riptutorial.com/es/home 38
esta función.
Hay algo interesante en Angular llamado Digest Cycle. El ciclo $ digest comienza como resultado
de una llamada a $ scope. $ Digest (). Supongamos que cambia un modelo de $ scope en una
función de controlador a través de la directiva ng-click. En ese caso, AngularJS activa
automáticamente un ciclo de $ digest llamando a $ digest (). Además de ng-click, hay otras
directivas / servicios incorporados que le permiten cambiar los modelos (por ejemplo, ng-model, $
timeout, etc.) y desencadenar automáticamente un ciclo $ digest. La implementación aproximada
de $ digest se ve así.
Scope.prototype.$digest = function() {
var dirty;
do {
dirty = this.$$digestOnce();
} while (dirty);
}
Scope.prototype.$$digestOnce = function() {
var self = this;
var newValue, oldValue, dirty;
_.forEach(this.$$watchers, function(watcher) {
newValue = watcher.watchFn(self);
oldValue = watcher.last; // It just remembers the last value for dirty checking
if (newValue !== oldValue) { //Dirty checking of References
// For Deep checking the object , code of Value
// based checking of Object should be implemented here
watcher.last = newValue;
watcher.listenerFn(newValue,
(oldValue === initWatchVal ? newValue : oldValue),
self);
dirty = true;
}
});
return dirty;
};
https://riptutorial.com/es/home 39
de Angular, que aún pueden cambiar las cosas en el alcance. Si envolvemos ese código en $
apply, se ocupará de llamar a $ digest (). Implementación aproximada de $ apply ().
Scope.prototype.$apply = function(expr) {
try {
return this.$eval(expr); //Evaluating code in the context of Scope
} finally {
this.$digest();
}
};
https://riptutorial.com/es/home 40
Capítulo 8: Compartir datos
Observaciones
Una pregunta muy común cuando se trabaja con Angular es cómo compartir datos entre
controladores. El uso de un servicio es la respuesta más frecuente y este es un ejemplo simple
que muestra un patrón de fábrica para compartir cualquier tipo de objeto de datos entre dos o
más controladores. Debido a que es una referencia de objeto compartido, una actualización en un
controlador estará disponible inmediatamente en todos los demás controladores que usen el
servicio. Tenga en cuenta que tanto el servicio y la fábrica y los dos proveedores .
Examples
Usando ngStorage para compartir datos
<head>
<title>Angular JS ngStorage</title>
<script src =
"http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="https://rawgithub.com/gsklee/ngStorage/master/ngStorage.js"></script>
</head>
También puede utilizar el localStorage y sessionStorage de HTML5 . Sin embargo, usar HTML5
https://riptutorial.com/es/home 41
localStorage requeriría que localStorage y deserialice sus objetos antes de usarlos o guardarlos.
Por ejemplo:
var myObj = {
firstname: "Nic",
lastname: "Raboy",
website: "https://www.google.com"
}
//if you wanted to save into localStorage, serialize it
window.localStorage.set("saved", JSON.stringify(myObj));
Podemos crear un service para set y get los datos entre los controllers y luego inyectar ese
servicio en la función del controlador donde queremos usarlo.
Servicio :
app.service('setGetData', function() {
var data = '';
getData: function() { return data; },
setData: function(requestData) { data = requestData; }
});
Controladores:
app.controller('myCtrl1', ['setGetData',function(setGetData) {
}]);
app.controller('myCtrl2', ['setGetData',function(setGetData) {
}]);
Aquí, podemos ver que myCtrl1 se usa para setting los datos y myCtrl2 se usa para getting los
datos. Entonces, podemos compartir los datos de un controlador a otro como este.
https://riptutorial.com/es/home 42
Capítulo 9: Componentes
Parámetros
Parámetro Detalles
@ Parámetros de la cadena.
- -
LifeCycle
Detalles (requiere angular.version> = 1.5.3)
Hooks
https://riptutorial.com/es/home 43
Observaciones
Componente es un tipo especial de directiva que usa una configuración más simple que es
adecuada para una estructura de aplicación basada en componentes. Los componentes se
introdujeron en Angular 1.5, los ejemplos en esta sección no funcionarán con versiones
anteriores de AngularJS.
Examples
Componentes básicos y ganchos de ciclo de vida
¿Qué es un componente?
• Un componente es básicamente una directiva que usa una configuración más simple y que
es adecuada para una arquitectura basada en componentes, que es de lo que trata Angular
2. Piense en un componente como un widget: un fragmento de código HTML que puede
reutilizar en varios lugares diferentes de su aplicación web.
Componente
angular.module('myApp', [])
.component('helloWorld', {
template: '<span>Hello World!</span>'
});
Margen
<div ng-app="myApp">
<hello-world> </hello-world>
</div>
Demo en vivo
angular.module("myApp", [])
.component("helloWorld",{
template: '<span>Hello {{$ctrl.name}}!</span>',
bindings: { name: '@' }
https://riptutorial.com/es/home 44
});
Margen
<div ng-app="myApp">
<hello-world name="'John'" > </hello-world>
</div>
Demo en vivo
angular.module("myApp", [])
.component("helloWorld",{
template: "Hello {{$ctrl.name}}, I'm {{$ctrl.myName}}!",
bindings: { name: '@' },
controller: function(){
this.myName = 'Alain';
}
});
Margen
<div ng-app="myApp">
<hello-world name="John"> </hello-world>
</div>
CodePen Demo
Los parámetros pasados al componente están disponibles en el alcance del controlador justo
antes $onInit función $onInit . Considera este ejemplo:
angular.module("myApp", [])
.component("helloWorld",{
template: "Hello {{$ctrl.name}}, I'm {{$ctrl.myName}}!",
bindings: { name: '@' },
controller: function(){
this.$onInit = function() {
this.myName = "Mac" + this.name;
}
}
});
https://riptutorial.com/es/home 45
Demo en vivo
Esto se puede lograr especificando que nuestro componente requiere ese componente principal,
el requisito nos dará una referencia al controlador de componente requerido, que luego se puede
usar en nuestro controlador como se muestra en el siguiente ejemplo:
Observe que se garantiza que los controladores necesarios estarán listos solo
después del gancho $ onInit.
angular.module("myApp", [])
.component("helloWorld",{
template: "Hello {{$ctrl.name}}, I'm {{$ctrl.myName}}!",
bindings: { name: '@' },
require: {
parent: '^parentComponent'
},
controller: function () {
// here this.parent might not be initiated yet
this.$onInit = function() {
// after $onInit, use this.parent to access required controller
this.parent.foo();
}
}
});
Sin embargo, tenga en cuenta que esto crea un acoplamiento estrecho entre el niño y el padre.
Componentes en angular JS
Los componentes en angularJS se pueden visualizar como una directiva personalizada (<html>
esto en una directiva HTML, y algo como esto será una directiva personalizada <CUALQUIER
COSA>). Un componente contiene una vista y un controlador. El controlador contiene la lógica de
negocio que está enlazada con una vista, que el usuario ve. El componente difiere de una
directiva angular porque contiene menos configuración. Un componente angular puede definirse
así.
angular.module("myApp",[]).component("customer", {})
Los componentes se definen en los módulos angulares. Contienen dos argumentos, uno es el
nombre del componente y el segundo es un objeto que contiene un par de valores clave, que
define qué vista y qué controlador va a usar de esta manera.
https://riptutorial.com/es/home 46
angular.module("myApp",[]).component("customer", {
templateUrl : "customer.html", // your view here
controller: customerController, //your controller here
controllerAs: "cust" //alternate name for your controller
})
<customer></customer>
Ahora esta directiva será reemplazada por la vista que ha especificado y la lógica de negocios
que ha escrito en su controlador.
NOTA: Recuerde que el componente toma un objeto como segundo argumento mientras que la
directiva toma una función de fábrica como argumento.
https://riptutorial.com/es/home 47
Capítulo 10: Constantes
Observaciones
MAYÚSCULAS su constante : escribir constante en mayúsculas es una buena práctica común
que se usa en muchos idiomas. También es útil identificar claramente la naturaleza de los
elementos inyectados:
Examples
Crea tu primera constante
angular
.module('MyApp', [])
.constant('VERSION', 1.0);
angular
.module('MyApp')
.controller('FooterController', function(VERSION) {
this.version = VERSION;
});
Casos de uso
No hay revolución aquí, pero la constante angular puede ser útil especialmente cuando tu
aplicación y / o equipo comienza a crecer ... ¡o si simplemente te encanta escribir código
hermoso!
• Código refactor. Ejemplo con los nombres de los eventos. Si utiliza muchos eventos en su
aplicación, tiene los nombres de los eventos un poco en todas partes. A cuando un nuevo
desarrollador se une a su equipo, nombra sus eventos con una sintaxis diferente, ... Puede
evitar esto fácilmente agrupando los nombres de sus eventos en una constante:
https://riptutorial.com/es/home 48
angular
.module('MyApp')
.constant('EVENTS', {
LOGIN_VALIDATE_FORM: 'login::click-validate',
LOGIN_FORGOT_PASSWORD: 'login::click-forgot',
LOGIN_ERROR: 'login::notify-error',
...
});
angular
.module('MyApp')
.controller('LoginController', function($scope, EVENT) {
$scope.$on(EVENT.LOGIN_VALIDATE_FORM, function() {
...
});
})
angular
.module('MyApp')
.constant('CONFIG', {
BASE_URL: {
APP: 'http://localhost:3000',
API: 'http://localhost:3001'
},
STORAGE: 'S3',
...
});
• Aislar las piezas. A veces, hay algunas cosas de las que no estás muy orgulloso ... como el
valor codificado, por ejemplo. En lugar de dejarlos en su código principal, puede crear una
constante angular
angular
.module('MyApp')
.constant('HARDCODED', {
KEY: 'KEY',
RELATION: 'has_many',
VAT: 19.6
});
$scope.settings = {
username: Profile.username,
relation: 'has_many',
vat: 19.6
}
https://riptutorial.com/es/home 49
a
$scope.settings = {
username: Profile.username,
relation: HARDCODED.RELATION,
vat: HARDCODED.VAT
}
https://riptutorial.com/es/home 50
Capítulo 11: Controladores
Sintaxis
• <htmlElement ng-controller = "controllerName"> ... </htmlElement>
• <script> app.controller ('controllerName', controllerFunction); </script>
Examples
Su primer controlador
Un controlador es una estructura básica que se usa en Angular para preservar el alcance y
manejar ciertas acciones dentro de una página. Cada controlador está acoplado con una vista
HTML.
A continuación se muestra una placa de referencia básica para una aplicación Angular:
<!DOCTYPE html>
<html ng-app='MyFirstApp'>
<script src="js/controllers.js"></script>
https://riptutorial.com/es/home 51
Necesitaremos un archivo Javascript donde defina sus controladores y sus acciones / datos.
El atributo ng-controller establece el controlador para ese elemento DOM y todos los elementos
que son hijos (recursivamente) debajo de él.
Puede tener múltiples del mismo controlador (en este caso, MyController ) diciendo ... as mc , le
estamos dando a esta instancia del controlador un alias.
La notación {{ ... }} es una expresión angular. En este caso, esto establecerá el texto interno de
ese elemento <h1> en cualquiera que sea el valor de mc.title .
Nota: Angular emplea enlace de datos de doble vía, lo que significa que, independientemente de
cómo actualice el valor de mc.title , se reflejará tanto en el controlador como en la página.
También tenga en cuenta que las expresiones angulares no tienen que hacer referencia a un
controlador. Una expresión Angular puede ser tan simple como {{ 1 + 2 }} o {{ "Hello " +
"World" }} .
<button ng-click="mc.clicked()">
ng-click es una directiva angular, en este caso, vincula el evento click para que el botón active la
función MyController clicked() de la instancia de MyController .
Con esas cosas en mente, escribamos una implementación del controlador MyController . Con el
ejemplo anterior, escribiría este código en js/controller.js .
Tenga en cuenta que el nombre que aprobamos aquí es el mismo que el que estableció en su
HTML con la directiva ng-app .
Ahora que tenemos el objeto de la aplicación, podemos usar eso para crear controladores.
app.controller('MyController', function(){
var ctrl = this;
ctrl.clicked = function(){
alert("MyController.clicked()");
};
});
https://riptutorial.com/es/home 52
Nota: Para cualquier cosa que queramos ser parte de la instancia del controlador, usamos this
palabra clave.
Creando Controladores
angular
.module('app')
.controller('SampleController', SampleController)
El segundo parámetro del método del controlador puede aceptar una matriz de dependencias.
Como puede ver, he definido $scope y $http que deberían corresponder a los parámetros de la
función del controlador en la que a será $scope , y b sería $http . Tenga en cuenta que el último
elemento de la matriz debe ser su función de controlador.
Esto hace lo mismo que la anotación de matriz en línea, pero proporciona un estilo diferente para
aquellos que prefieren una opción sobre la otra.
https://riptutorial.com/es/home 53
Al inyectar dependencias utilizando la forma de matriz, asegúrese de que la lista de dependencias
coincida con la lista correspondiente de los argumentos pasados a la función del controlador.
Tenga en cuenta que en el siguiente ejemplo, $scope y $http se invierten. Esto causará un
problema en el código.
// Intentional Bug: injected dependencies are reversed which will cause a problem
app.controller('sampleController', ['$scope', '$http',function($http, $scope) {
$http.get('sample.json');
}]);
En Angular $scope es el pegamento entre el controlador y la vista que ayuda con todas nuestras
necesidades de enlace de datos. Controlador Como es otra forma de enlazar el controlador y la
vista, y se recomienda su uso en su mayoría. Básicamente, estas son las dos construcciones de
controlador en Angular (es decir, $ scope y Controller As).
function CustomerController() {
this.name = {};
this.sendMessage = function() { };
}
controladorAs con vm
function CustomerController() {
/*jshint validthis: true */
var vm = this;
vm.name = {};
vm.sendMessage = function() { };
}
controllerAs es azúcar sintáctica sobre $scope . Todavía puede enlazar a los métodos Ver y
todavía tener acceso a $scope . El uso de controllerAs es una de las mejores prácticas sugeridas
por el equipo de núcleo angular. Hay muchas razones para esto, algunas de ellas son:
• $scope está exponiendo a los miembros del controlador a la vista a través de un objeto
intermediario. Al configurar this.* , Podemos exponer solo lo que queremos exponer desde
el controlador a la vista. También sigue la forma estándar de JavaScript de usar esto.
https://riptutorial.com/es/home 54
la propiedad principal utilizando el nombre de alias del controlador principal en lugar de usar
la sintaxis de $parent .
• Promueve el uso del enlace a un objeto "punteado" en la Vista (por ejemplo, customer.name
en lugar del nombre), que es más contextual, más fácil de leer y evita cualquier problema de
referencia que pueda ocurrir sin "puntos".
• Use una variable de captura para esto cuando use la sintaxis de controllerAs . Elija un
nombre de variable consistente como vm , que significa ViewModel. Porque, this palabra
clave es contextual y cuando se usa dentro de una función dentro de un controlador puede
cambiar su contexto. Capturar el contexto de esto evita encontrar este problema.
Para crear controladores angulares seguros para la minificación, cambiará los parámetros de la
función del controller .
El segundo argumento en la función module.controller debe pasar una matriz , donde el último
parámetro es la función del controlador , y cada parámetro anterior es el nombre de cada valor
inyectado.
Esto es diferente del paradigma normal; que toma la función de controlador con los argumentos
inyectados.
Dado:
app.controller('ctrlInject',
[
/* Injected Parameters */
'$Injectable1',
'$Injectable2',
/* Controller Function */
function($injectable1Instance, $injectable2Instance) {
/* Controller Content */
}
]
);
https://riptutorial.com/es/home 55
Nota: No es necesario que los nombres de los parámetros inyectados coincidan, pero se unirán
en orden.
var
a=angular.module('myApp');a.controller('ctrlInject',['$Injectable1','$Injectable2',function(b,c){/*
Controller Content */}]);
Controladores anidados
Los controladores de anidamiento también encadenan el $scope . Cambiar una variable de $scope
en el controlador anidado cambia la misma variable de $scope en el controlador principal.
$scope.childFunction = function () {
$scope.parentVariable = "I'm overriding you";
};
});
<body ng-controller="parentController">
What controller am I? {{parentVariable}}
<div ng-controller="childController">
What controller am I? {{childVariable}}
<button ng-click="childFunction()"> Click me to override! </button>
</div>
</body>
Los controladores de anidamiento pueden tener sus beneficios, pero una cosa debe tenerse en
cuenta al hacerlo. Llamar a la directiva ngController crea una nueva instancia del controlador, que
a menudo puede crear confusión y resultados inesperados.
https://riptutorial.com/es/home 56
Capítulo 12: Controladores con ES6
Examples
Controlador
es muy fácil escribir un controlador angularJS con ES6 si está familiarizado con la programación
orientada a objetos :
class exampleContoller{
constructor(service1,service2,...serviceN){
let ctrl=this;
ctrl.service1=service1;
ctrl.service2=service2;
.
.
.
ctrl.service1=service1;
ctrl.controllerName = 'Example Controller';
ctrl.method1(controllerName)
method1(param){
let ctrl=this;
ctrl.service1.serviceFunction();
.
.
ctrl.scopeName=param;
}
.
.
.
methodN(param){
let ctrl=this;
ctrl.service1.serviceFunction();
.
.
}
}
exampleContoller.$inject = ['service1','service2',...,'serviceN'];
export default exampleContoller;
https://riptutorial.com/es/home 57
Capítulo 13: Decoradores
Sintaxis
• decorador (nombre, decorador);
Observaciones
Decorador es una función que permite modificar un servicio , una fábrica , una
directiva o un filtro antes de su uso. Decorator se utiliza para anular o modificar el
comportamiento del servicio. El valor de retorno de la función de decoración puede ser
el servicio original o un nuevo servicio que reemplaza, o envuelve y delega, el servicio
original.
Uno debería considerar usar el decorador solo si cualquier otro enfoque no es apropiado o resulta
ser demasiado tedioso. Si la aplicación grande usa el mismo servicio y una parte cambia el
comportamiento del servicio, es fácil crear confusión y / o errores en el proceso.
El caso de uso típico sería cuando tiene una dependencia de terceros que no puede actualizar,
pero necesita que funcione de manera diferente o que la extienda.
Examples
Servicio de decoración, fábrica.
angular.module('app', [])
.config(function($provide) {
$provide.decorator('myService', function($delegate) {
$delegate.getDate = function() { // override with actual date object
return new Date();
};
return $delegate;
});
})
https://riptutorial.com/es/home 58
.service('myService', function() {
this.getDate = function() {
return null; // w/o decoration we'll be returning null
};
})
.controller('myController', function(myService) {
var vm = this;
vm.date = myService.getDate();
});
Decorar directiva
Las directivas se pueden decorar como servicios y podemos modificar o reemplazar cualquiera de
sus funciones. Tenga en cuenta que se accede a la directiva en la posición 0 en $ matriz de
delegado y el parámetro de nombre en el decorador debe incluir el sufijo de la Directive (distingue
entre mayúsculas y minúsculas).
Por lo tanto, si la directiva se llama myDate , se puede acceder a ella usando myDateDirective
usando $delegate[0] .
<body>
<my-date></my-date>
</body>
angular.module('app', [])
.config(function($provide) {
$provide.decorator('myDateDirective', function($delegate, $interval) {
var directive = $delegate[0]; // access directive
return $delegate;
});
})
https://riptutorial.com/es/home 59
.directive('myDate', function() {
return {
restrict: 'E',
template: '<span>Current time is {{ date | date:\'MM:ss\' }}</span>',
link: function(scope) {
scope.date = new Date(); // get current date
}
};
});
Decorar filtro
Al decorar filtros, el parámetro de nombre debe incluir el sufijo de Filter (distingue entre
mayúsculas y minúsculas). Si el filtro se llama repeat , el parámetro decorador es repeatFilter . A
continuación, decoraremos el filtro personalizado que repite cualquier cadena dada n veces para
que el resultado se invierta. También puede decorar los filtros incorporados de angular de la
misma forma, aunque no se recomienda ya que puede afectar la funcionalidad del marco.
<body>
<div ng-bind="'i can haz cheeseburger ' | repeat:2"></div>
</body>
angular.module('app', [])
.config(function($provide) {
$provide.decorator('repeatFilter', function($delegate) {
return function reverse(input, count) {
// reverse repeated string
return ($delegate(input, count)).split('').reverse().join('');
};
});
})
.filter('repeat', function() {
return function(input, count) {
// repeat string n times
return (input || '').repeat(count || 1);
};
});
https://riptutorial.com/es/home 60
Capítulo 14: Depuración
Examples
Depuración básica en el marcado.
angular.module('demoApp', [])
.controller('mainController', MainController);
function MainController() {
var vm = this;
vm.items = [{
id: 0,
text: 'first'
},
{
id: 1,
text: 'second'
},
{
id: 2,
text: 'third'
}];
}
A veces puede ayudar a ver si hay un nuevo alcance para solucionar los problemas de alcance.
$scope.$id puede usarse en una expresión en cualquier parte de su marca para ver si hay un
nuevo $ scope.
Una salida del modelo en una etiqueta previa es útil para ver los datos actuales de su modelo. El
filtro json crea una salida con formato de aspecto agradable. La etiqueta previa se usa porque
dentro de esa etiqueta se mostrará correctamente cualquier carácter de línea nueva \n .
https://riptutorial.com/es/home 61
manifestación
https://riptutorial.com/es/home 62
$events -- events present on the selected node (requires jQuery)
https://riptutorial.com/es/home 63
El rendimiento de la aplicación se puede monitorear contando el no.de ámbitos, aislar los
microscopios, observadores y oyentes de la aplicación.
Use $count() para obtener el recuento de ámbitos, aislar microscopios, observadores y oyentes.
https://riptutorial.com/es/home 64
Nota: esta extensión solo funcionará cuando debugInfo esté habilitado.
En una aplicación angular, todo va alrededor del alcance, si pudiéramos obtener un alcance de
elementos, entonces es fácil depurar la aplicación angular. Cómo acceder al alcance del
elemento:
angular.element(myDomElement).scope();
e.g.
angular.element(document.getElementById('yourElementId')).scope() //accessing by ID
https://riptutorial.com/es/home 65
Conseguir el alcance del controlador: -
angular.element('[ng-controller=ctrl]').scope()
Otra forma fácil de acceder a un elemento DOM desde la consola (como se mencionó jm) es
haciendo clic en él en la pestaña 'elementos', y se almacena automáticamente como $ 0.
angular.element($0).scope();
https://riptutorial.com/es/home 66
Capítulo 15: directiva de clase ng
Examples
Tres tipos de expresiones de clase ng
1. cuerda
<span ng-class="MyClass">Sample Text</span>
Especificar una expresión que se evalúa como una cadena le dice a Angular que la trate como
una variable de $ scope. Angular verificará $ scope y buscará una variable llamada "MyClass".
Cualquiera que sea el texto contenido en "MyClass" se convertirá en el nombre real de la clase
que se aplica a este <span> . Puede especificar varias clases separando cada clase con un
espacio.
Angular evaluará la expresión MyClass y encontrará la definición de $ scope. Aplicará las tres
clases "rojo negrita", "borrado" y "error" al elemento <span> .
Especificar clases de esta manera le permite cambiar fácilmente las definiciones de clase en su
controlador. Por ejemplo, es posible que deba cambiar la clase según las interacciones de otros
usuarios o los nuevos datos que se cargan desde el servidor. Además, si tiene muchas
expresiones para evaluar, puede hacerlo en una función que define la lista final de clases en una
variable de $scope . Esto puede ser más fácil que intentar incluir muchas evaluaciones en el
atributo ng-class en su plantilla HTML.
2. Objeto
Esta es la forma más comúnmente utilizada de definir clases usando ng-class porque le permite
especificar evaluaciones que determinan qué clase usar.
Especifique un objeto que contiene pares clave-valor. La clave es el nombre de la clase que se
aplicará si el valor (un condicional) se evalúa como verdadero.
<style>
.red { color: red; font-weight: bold; }
https://riptutorial.com/es/home 67
.blue { color: blue; }
.green { color: green; }
.highlighted { background-color: yellow; color: black; }
</style>
<span ng-class="{ red: ShowRed, blue: ShowBlue, green: ShowGreen, highlighted: IsHighlighted
}">Sample Text</span>
3. Array
Una expresión que se evalúa como una matriz le permite usar una combinación de cadenas (vea
el número 1 arriba) y los objetos condicionales (número 2 arriba).
<style>
.bold { font-weight: bold; }
.strike { text-decoration: line-through; }
.orange { color: orange; }
</style>
Esto crea un campo de entrada de texto vinculado a la variable de alcance UserStyle que permite
al usuario escribir cualquier nombre de clase. Estos se aplicarán dinámicamente al elemento <p>
según los tipos de usuario. Además, el usuario puede hacer clic en la casilla de verificación que
está vinculada a la variable de alcance de warning . Esto también se aplicará dinámicamente al
elemento <p> .
https://riptutorial.com/es/home 68
Capítulo 16: Directivas incorporadas
Examples
Expresiones angulares - Texto vs. Número
Este ejemplo demuestra cómo se evalúan las expresiones angulares cuando se usa type="text" y
type="number" para el elemento de entrada. Considere el siguiente controlador y vea:
Controlador
app.controller('ctrl', function($scope) {
$scope.textInput = {
value: '5'
};
$scope.numberInput = {
value: 5
};
});
Ver
*- Eso es hasta que el usuario cambia el valor en el campo de entrada, luego la pantalla
cambiará en consecuencia.
Ejemplo de trabajo
ngRepetir
ng-repeat es una directiva integrada en Angular que le permite iterar una matriz o un objeto y le
permite repetir un elemento una vez para cada elemento de la colección.
<ul>
https://riptutorial.com/es/home 69
<li ng-repeat="item in itemCollection">
{{item.Name}}
</li>
</ul>
Dónde:
item = item individual en la colección
itemCollection = La matriz que está iterando
ng-repetir un objeto
<ul>
<li ng-repeat="(key, value) in myObject">
{{key}} : {{value}}
</li>
</ul>
Dónde:
clave = el nombre de la propiedad
valor = el valor de la propiedad
myObject = el objeto que estás iterando
Dónde:
searchText = el texto por el cual el usuario quiere filtrar la lista
stringArray = una matriz de cadenas, por ejemplo, ['string', 'array']
También puede mostrar o hacer referencia a los elementos filtrados en otro lugar asignando un
alias de salida de filtro as aliasName , de este modo:
https://riptutorial.com/es/home 70
ng-repeat-start y ng-repeat-end
Para repetir varios elementos de DOM definiendo un inicio y un punto final, puede usar las
directivas ng-repeat-start y ng-repeat-end .
<ul>
<li ng-repeat-start="item in [{a: 1, b: 2}, {a: 3, b:4}]">
{{item.a}}
</li>
<li ng-repeat-end>
{{item.b}}
</li>
</ul>
Salida:
• 1
• 2
• 3
• 4
Variables
Consideraciones de rendimiento
Si los objetos de la colección tienen una propiedad de identificador, siempre debe track by el
https://riptutorial.com/es/home 71
identificador en lugar de todo el objeto, que es la funcionalidad predeterminada. Si no hay ningún
identificador presente, siempre puede usar el $index incorporado.
Alcance de ngRepeat
ngRepeatsiempre creará un ámbito secundario aislado, por lo que se debe tener cuidado si se
debe acceder al ámbito principal dentro de la repetición.
Este es un ejemplo simple que muestra cómo puede establecer un valor en su ámbito principal
desde un evento de clic dentro de ngRepeat .
$scope.val = 0;
this.val = 0;
$scope.itemCollection = [{
id: 0,
value: 4.99,
label: 'Football'
},
{
id: 1,
value: 6.99,
label: 'Baseball'
},
{
id: 2,
value: 9.99,
label: 'Basketball'
}];
Si solo había val = item.value en ng-click , no se actualizará el val en el ámbito principal debido
al ámbito aislado. Es por eso que se accede al alcance principal con $parent referencia de $parent
o con la sintaxis de controllerAs (por ejemplo, ng-controller="mainController as ctrl" ).
Anidado ng-repetir
https://riptutorial.com/es/home 72
</div>
Aquí para acceder al índice de padre ng-repeat dentro de hijo ng-repeat, puede usar
$parent.$index .
ngShow y ngOcultar
La directiva ng-hide es similar. Sin embargo, si el valor es falsy, mostrará el elemento HTML.
Cuando la expresión sea veraz la esconderá.
Controlador :
angular.module('app')
.controller('ExampleController', ExampleController);
function ExampleController() {
var vm = this;
Ver
<p>Enter Password</p>
<input ng-model="main.username" type="text">
<hr>
https://riptutorial.com/es/home 73
Your username is free to use!
</div>
</section>
ngOpciones
ngOptions es una directiva que simplifica la creación de un cuadro desplegable html para la
selección de un elemento de una matriz que se almacenará en un modelo. El atributo ngOptions
se usa para generar dinámicamente una lista de elementos <option> para el elemento <select>
usando la matriz u objeto obtenido al evaluar la expresión de comprensión ngOptions.
Con ng-options el marcado se puede reducir a solo una etiqueta de selección y la directiva creará
la misma selección:
<select ng-model="selectedFruitNgOptions"
ng-options="curFruit as curFruit.label for curFruit in fruit">
</select>
Hay otra forma de crear opciones de select usando ng-repeat , pero no se recomienda usar ng-
repeat ya que se usa principalmente para fines generales como, por ejemplo, forEach solo para
hacer un bucle. Mientras que ng-options es específicamente para crear opciones de etiqueta
select .
<select ng-model="selectedFruit">
<option ng-repeat="curFruit in fruit" value="{{curFruit}}">
{{curFruit.label}}
</option>
</select>
EJEMPLO COMPLETO
$scope.fruit = [
{ label: "Apples", value: 4, id: 2 },
{ label: "Oranges", value: 2, id: 1 },
{ label: "Limes", value: 4, id: 4 },
{ label: "Lemons", value: 5, id: 3 }
];
https://riptutorial.com/es/home 74
<!-- label for value in array -->
<select ng-options="f.label for f in fruit" ng-model="selectedFruit"></select>
Efectos:
EJEMPLO COMPLETO
Efectos:
f.value (4) será el valor en este caso mientras la etiqueta siga siendo la misma.
EJEMPLO COMPLETO
Efectos:
Las opciones se agruparán en función de su value . Las opciones con el mismo value caerán en
una categoría
EJEMPLO COMPLETO
https://riptutorial.com/es/home 75
<option disabled="" value="{ label: "Apples", value: 4, id: 2 }"> Apples </option>
Efectos:
EJEMPLO COMPLETO
<!-- label group by group for value in array track by trackexpr -->
<select ng-options="f.value as f.label group by f.value for f in fruit track by f.id" ng-
model="selectedFruit"></select>
Efectos:
No hay cambios visuales cuando se utiliza trackBy , pero Angular detectará los cambios por id
lugar de por referencia, lo que siempre es una solución mejor.
EJEMPLO COMPLETO
<option disabled="" value="{ label: "Apples", value: 4, id: 2 }"> Apples </option>
Efectos:
orderByes un filtro estándar de AngularJS que organiza las opciones en orden ascendente (por
defecto), por lo que "Naranjas" aparecerá en primer lugar desde su id = 1.
EJEMPLO COMPLETO
ngModel
Con ng-model puedes vincular una variable a cualquier tipo de campo de entrada. Puede mostrar
la variable utilizando llaves dobles, por ejemplo, {{myAge}} .
https://riptutorial.com/es/home 76
<p>{{myName}}</p>
A medida que ingresa el campo de entrada o lo modifica de alguna manera, verá el valor en la
actualización del párrafo al instante.
Necesitará consultar el alcance del controlador antes de que el alias del controlador definido en el
atributo ng-controller a la variable ng-model. De esta manera, no necesitará inyectar $scope en su
controlador para hacer referencia a su variable ng-model, la variable estará disponible como
this.myName dentro de la función de su controlador.
clase ng
Supongamos que necesita mostrar el estado de un usuario y que tiene varias clases posibles de
CSS que podrían usarse. Angular hace que sea muy fácil elegir de una lista de varias clases
posibles que le permiten especificar una lista de objetos que incluye condicionales. Angular es
capaz de usar la clase correcta basada en la veracidad de los condicionales.
Su objeto debe contener pares clave / valor. La clave es un nombre de clase que se aplicará
cuando el valor (condicional) se evalúe como verdadero.
<style>
.active { background-color: green; color: white; }
.inactive { background-color: gray; color: white; }
.adminUser { font-weight: bold; color: yellow; }
.regularUser { color: white; }
</style>
<span ng-class="{
active: user.active,
inactive: !user.active,
adminUser: user.level === 1,
regularUser: user.level === 2
}">John Smith</span>
Angular verificará el objeto $scope.user para ver el estado active y el número de level .
Dependiendo de los valores en esas variables, Angular aplicará el estilo correspondiente a <span>
.
ngIf
ng-ifes una directiva similar a ng-show pero inserta o elimina el elemento del DOM en lugar de
simplemente ocultarlo. Angular 1.1.5 introdujo la directiva ng-if. Puede usar la directiva ng-if por
encima de las versiones 1.1.5. Esto es útil porque Angular no procesará los resúmenes de los
https://riptutorial.com/es/home 77
elementos dentro de un ng-if eliminado ng-if reduce la carga de trabajo de Angular,
especialmente para los enlaces de datos complejos.
A diferencia de ng-show , la directiva ng-if crea un ámbito secundario que usa herencia prototípica.
Esto significa que establecer un valor primitivo en el ámbito secundario no se aplicará al padre.
Para establecer una primitiva en el ámbito $parent propiedad $parent en el ámbito secundario
deberá utilizarse.
JavaScript
angular.module('MyApp', []);
Ver
<div ng-controller="myController">
<div ng-if="currentUser">
Hello, {{currentUser}}
</div>
<div ng-if="!currentUser">
<a href="/login">Log In</a>
<a href="/register">Register</a>
</div>
</div>
<div ng-controller="myController">
<!-- ng-if: currentUser -->
<div ng-if="!currentUser">
<a href="/login">Log In</a>
<a href="/register">Register</a>
</div>
https://riptutorial.com/es/home 78
</div>
Ejemplo de trabajo
Promesa de la función
La directiva ngIf también acepta funciones, que lógicamente requieren devolver verdadero o falso.
<div ng-if="myFunction()">
<span>Span text</span>
</div>
$scope.myFunction = function() {
var result = false;
// Code to determine the boolean value of result
return result;
};
ngMouseenter y ngMouseleave
Las ng-mouseenter y ng-mouseleave son útiles para ejecutar eventos y aplicar el estilo CSS cuando
se desplaza dentro o fuera de sus elementos DOM.
HTML
En el ejemplo anterior, cuando el usuario apunta su mouse sobre el div , applyStyle cambia a true
, que a su vez aplica la clase .active CSS en la ng-class .
La directiva ng-mouseleave ejecuta una expresión y un evento de salida del mouse (cuando el
usuario retira el cursor del mouse del elemento DOM en el que reside esta directiva)
HTML
Reutilizando el primer ejemplo, ahora cuando el usuario le quita el puntero del mouse de la
.active , la clase .active se elimina.
https://riptutorial.com/es/home 79
deshabilitado
Esta directiva es útil para limitar los eventos de entrada basados en ciertas condiciones
existentes.
La directiva ng-disabled acepta una expresión que debe evaluar valores verdaderos o falsos.
HTML
ngDblclick
La directiva ng-dblclick es útil cuando desea vincular un evento de doble clic en sus elementos
DOM.
HTML
En el ejemplo anterior, el valor retenido en la input se incrementará cuando se haga doble clic en
el botón.
https://riptutorial.com/es/home 80
ng-checked Establece la casilla de verificación.
ng-model Enlaza elementos de entrada, selección, área de texto, etc. con propiedad de modelo.
ng-repeat Se utiliza para recorrer cada elemento de una colección para crear una nueva plantilla.
ng-classeven Funciona en conjunto con ngRepeat y surte efecto solo en filas impares (pares).
ng-classodd Funciona junto con ngRepeat y surte efecto solo en filas impares (pares).
https://riptutorial.com/es/home 81
ng-cut Se utiliza para especificar el comportamiento personalizado en el evento de corte.
ng-options Se utiliza para generar dinámicamente una lista de elementos para el elemento.
ng-list Se utiliza para convertir una cadena en una lista en función del delimitador especificado.
Haga clic en
Es útil cuando desea adjuntar eventos de clic en los botones y manejarlos en su controlador.
Esta directiva acepta una expresión con el objeto de eventos disponible como $event
HTML
Controlador
.controller("ctrl", function($scope) {
$scope.onClick = function(evt) {
console.debug("Hello click event: %o ",evt);
}
})
HTML
HTML
https://riptutorial.com/es/home 82
</button>
<span>
count: {{count}}
</span>
Controlador
...
$scope.count = function(){
$scope.count = $scope.count + 1;
}
...
Cuando se hace clic en el botón, una invocación de la función onClick imprimirá "Hola evento de
clic" seguido del objeto de evento.
ngRequisito
Se usa para definir opcionalmente si se requiere que un elemento de input tenga un valor no
vacío. La directiva es útil cuando se diseña la validación en formularios HTML complejos.
HTML
ng-model-options
Esta directiva acepta una expresión que evaluará un objeto de definición o una referencia a un
valor de alcance.
Ejemplo:
El ejemplo anterior adjuntará un efecto de rebote de 500 milisegundos en myValue , lo que hará
que el modelo se actualice 500 ms después de que el usuario haya terminado de escribir sobre la
input (es decir, cuando myValue finalizado la actualización).
https://riptutorial.com/es/home 83
ng-model-options="{ updateOn: 'blur'}" // will update on blur
3. allowInvalid : un indicador booleano que permite un valor no válido para el modelo, evitando
la validación de formularios por defecto, de forma predeterminada, estos valores se tratarían
como undefined .
4. getterSetter : un indicador booleano que indica si se debe tratar el ng-model como una
función getter / setter en lugar de un valor de modelo simple. La función se ejecutará y
devolverá el valor del modelo.
Ejemplo:
5. timezone : define la zona horaria para el modelo si la entrada es de la date o la time . tipos
capa ng
HTML
<div ng-cloak>
<h1>Hello {{ name }}</h1>
</div>
ngCloakse puede aplicar al elemento del cuerpo, pero el uso preferido es aplicar varias directivas
ngCloak a pequeñas porciones de la página para permitir la representación progresiva de la vista
del navegador.
ngIncluir
Un ejemplo es:
https://riptutorial.com/es/home 84
<div ng-include
src="'/gridview'"
ng-controller='gridController as gc'>
</div>
Tenga en cuenta que la /gridview deberá ser servida por el servidor web como una URL distinta y
legítima.
Además, tenga en cuenta que el atributo src acepta una expresión angular. Esto podría ser una
variable o una función llamada, por ejemplo, o, como en este ejemplo, una constante de cadena.
En este caso, debe asegurarse de envolver la URL de origen entre comillas simples , para
que se evalúe como una constante de cadena. Esta es una fuente común de confusión.
Dentro de /gridview html, puede referirse a gridController como si estuviera envuelto alrededor
de la página, por ejemplo:
<div class="row">
<button type="button" class="btn btn-default" ng-click="gc.doSomething()"></button>
</div>
ngSrc
El uso del marcado angular como {{hash}} en un atributo src no funciona bien. El navegador
buscará desde la URL con el texto literal {{hash}} hasta que Angular reemplace la expresión
dentro de {{hash}} . ng-src directiva ng-src anula el atributo src original para el elemento de
etiqueta de imagen y resuelve el problema
ngPatrón
La directiva ng-pattern acepta una expresión que se evalúa como un patrón de expresión regular
y usa ese patrón para validar una entrada de texto.
Ejemplo:
Digamos que queremos que un elemento <input> sea válido cuando su valor (ng-model) es una
dirección IP válida.
Modelo:
Controlador:
$scope.ipRegex = /\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-
https://riptutorial.com/es/home 85
9]|[01]?[0-9][0-9]?)\b/;
ngValue
<script>
angular.module('valueExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.names = ['pizza', 'unicorns', 'robots'];
$scope.my = { favorite: 'unicorns' };
}]);
</script>
<form ng-controller="ExampleController">
<h2>Which is your favorite?</h2>
<label ng-repeat="name in names" for="{{name}}">
{{name}}
<input type="radio"
ng-model="my.favorite"
ng-value="name"
id="{{name}}"
name="favorite">
</label>
<div>You chose {{my.favorite}}</div>
</form>
Plnkr de trabajo
ngCopy
En el controlador
$scope.blockCopy = function(event) {
event.preventDefault();
console.log("Copying won't work");
}
ngPaste
https://riptutorial.com/es/home 86
ngHref
ngHref se usa en lugar del atributo href, si tenemos expresiones angulares dentro del valor href.
La directiva ngHref anula el atributo href original de una etiqueta html usando el atributo href como
etiqueta, etiqueta, etc.
La directiva ngHref asegura que el enlace no esté roto, incluso si el usuario hace clic en el enlace
antes de que AngularJS haya evaluado el código.
Ejemplo 1
Ejemplo 2 Este ejemplo obtiene dinámicamente el valor href del cuadro de entrada y lo carga
como valor href.
Ejemplo 3
<script>
angular.module('angularDoc', [])
.controller('myController', function($scope) {
// Set some scope value.
// Here we set bootstrap version.
$scope.bootstrap_version = '3.3.7';
ngList
La directiva ng-list se usa para convertir una cadena delimitada de una entrada de texto a una
matriz de cadenas o viceversa.
Puede configurar el delimitador manualmente asignando ng-list un delimitador como este ng-
list="; " .
Por defecto, ng-list tiene un atributo ng-trim que se establece en verdadero. ng-trim cuando es
https://riptutorial.com/es/home 87
falso, respetará el espacio en blanco en su delimitador. De forma predeterminada, ng-list no
tiene en cuenta el espacio en blanco a menos que establezca ng-trim="false" .
Ejemplo:
angular.module('test', [])
.controller('ngListExample', ['$scope', function($scope) {
$scope.list = ['angular', 'is', 'cool!'];
}]);
Un delimitador del cliente se establece para ser ; . Y el modelo del cuadro de entrada se
establece en la matriz que se creó en el ámbito.
https://riptutorial.com/es/home 88
Capítulo 17: Directivas personalizadas
Introducción
Aquí aprenderá sobre la característica de directivas de AngularJS. A continuación encontrará
información sobre qué son las directivas, así como ejemplos básicos y avanzados de cómo
usarlas.
Parámetros
Parámetro Detalles
Permite que la directiva pase datos a una expresión para ser evaluada en
alcance: {&}
el padre.
https://riptutorial.com/es/home 89
Parámetro Detalles
https://riptutorial.com/es/home 90
Parámetro Detalles
Examples
Crear y consumir directivas personalizadas.
Las directivas son una de las características más poderosas de angularjs. Las directivas
angulosas personalizadas se usan para ampliar la funcionalidad de html creando nuevos
elementos html o atributos personalizados para proporcionar cierto comportamiento a una
etiqueta html.
directiva.js
// If you already have the app module created, comment the above line and create a reference
of the app module
var demoApp = angular.module("demoApp");
demoApp.directive('demoDirective', function () {
// The values of scope property decides how the actual scope is created and used inside a
directive. These values can be either “false”, “true” or “{}”. This creates an isolate scope
for the directive.
// '@' binding is for passing strings. These strings support {{}} expressions for
interpolated values.
// '=' binding is for two-way model binding. The model in parent scope is linked to the
model in the directive's isolated scope.
// '&' binding is for passing a method into your directive's scope so that it can be
called within your directive.
// The method is pre-bound to the directive's parent scope, and supports arguments.
https://riptutorial.com/es/home 91
scope: {
name: "@", // Always use small casing here even if it's a mix of 2-3 words
},
// compile is called during application initialization. AngularJS calls it once when html
page is loaded.
compile: function(element, attributes) {
element.css("border", "1px solid #cccccc");
// linkFunction is linked with each element with scope to get the element specific data.
var linkFunction = function($scope, element, attributes) {
element.html("Name: <b>"+$scope.name +"</b>");
element.css("background-color", "#ff00ff");
};
return linkFunction;
}
};
});
<html>
<head>
<title>Angular JS Directives</title>
</head>
<body>
<script src =
"http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="directive.js"></script>
<div ng-app = "demoApp">
<!-- Notice we are using Spinal Casing here -->
<demo-directive name="World"></demo-directive>
</div>
</body>
</html>
demoApp.directive('demoDirective', function () {
var directiveDefinitionObject = {
multiElement:
priority:
terminal:
scope: {},
bindToController: {},
controller:
controllerAs:
require:
restrict:
templateNamespace:
template:
templateUrl:
transclude:
https://riptutorial.com/es/home 92
compile:
link: function(){}
};
return directiveDefinitionObject;
});
1. multiElement - establecido en verdadero y todos los nodos DOM entre el inicio y el final del
nombre de la directiva se recopilarán y agruparán como elementos de la directiva
2. priority : permite la especificación del orden para aplicar directivas cuando se definen
múltiples directivas en un solo elemento DOM. Las directivas con números más altos se
compilan primero.
3. terminal : se establece en verdadero y la prioridad actual será el último conjunto de
directivas para ejecutar
4. scope : establece el ámbito de la directiva.
5. bind to controller : vincula las propiedades del ámbito directamente al controlador de
directivas
6. controller - función constructor controlador
7. require - requiere otra directiva e inyectar su controlador como el cuarto argumento de la
función de enlace.
8. controllerAs : referencia de nombre al controlador en el ámbito de la directiva para permitir
que se haga referencia al controlador desde la plantilla de la directiva.
9. restrict : restringir la directiva a Elemento, Atributo, Clase o Comentario
10. templateNameSpace : establece el tipo de documento utilizado por la plantilla de directiva: html,
svg o math. html es el predeterminado
11. template : marca html que por defecto reemplaza el contenido del elemento de la directiva, o
envuelve el contenido del elemento de la directiva si la transclusión es verdadera
12. templateUrl - url proporcionada de forma asíncrona para la plantilla
13. transclude : extraiga el contenido del elemento donde aparece la directiva y haga que esté
disponible para la directiva. Los contenidos se compilan y se proporcionan a la directiva
como una función de transclusión.
14. compile - función para transformar la plantilla DOM
15. link : solo se utiliza si la propiedad de compilación no está definida. La función de enlace es
responsable de registrar los escuchas de DOM y de actualizar el DOM. Se ejecuta después
de que la plantilla ha sido clonada.
superman-directiva.js
angular.module('myApp', [])
.directive('superman', function() {
return {
// restricts how the directive can be used
restrict: 'E',
templateUrl: 'superman-template.html',
controller: function() {
this.message = "I'm superman!"
},
controllerAs: 'supermanCtrl',
// Executed after Angular's initialization. Use commonly
https://riptutorial.com/es/home 93
// for adding event handlers and DOM manipulation
link: function(scope, element, attributes) {
element.on('click', function() {
alert('I am superman!')
});
}
}
});
superman-template.html
<h2>{{supermanCtrl.message}}</h2>
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
<script src="superman-directive.js"><script/>
</head>
<body>
<div ng-app="myApp">
<superman></superman>
</div>
</body>
</html>
Puede consultar más sobre las funciones de restrict y link la directiva en la documentación
oficial de AngularJS sobre directivas
Las directivas AngularJS son las que controlan la representación del HTML dentro de una
aplicación AngularJS. Pueden ser un elemento HTML, atributo, clase o un comentario. Las
directivas se utilizan para manipular el DOM, adjuntando nuevos comportamientos a elementos
HTML, enlace de datos y muchos más. Algunos de los ejemplos de directivas que proporciona
angular son ng-model, ng-hide, ng-if.
Del mismo modo, uno puede crear su propia directiva personalizada y hacerlos valiosos. Para
crear referencias de directivas personalizadas. El sentido detrás de la creación de directivas
reutilizables es hacer un conjunto de directivas / componentes escritos por usted, tal como
angularjs nos proporciona el uso de angular.js. Estas directivas reutilizables pueden ser
particularmente muy útiles cuando tiene un conjunto de aplicaciones / aplicación que requiere un
comportamiento y apariencia consistentes. Un ejemplo de dicho componente reutilizable puede
ser una barra de herramientas simple que puede usar en su aplicación o en diferentes
aplicaciones, pero desea que se comporten igual o se vean igual.
https://riptutorial.com/es/home 94
reutilizableModuleApp.js:
(function(){
//Remember whatever dependencies you have in here should be injected in the app module where
it is intended to be used or it's scripts should be included in your main app
//We will be injecting ng-sanitize
resubaleModuleApp.directive('toolbar', toolbar)
toolbar.$inject=['$sce'];
function toolbar($sce){
return{
restrict :'AE',
//Defining below isolate scope actually provides window for the directive to take data
from app that will be using this.
scope : {
value1: '=',
value2: '=',
},
}
template : '<ul> <li><a ng-click="Add()" href="">{{value1}}</a></li> <li><a ng-
click="Edit()" href="#">{{value2}}</a></li> </ul> ',
link : function(scope, element, attrs){
};
};
}
}
});
mainApp.js:
(function(){
var mainApp = angular.module('mainApp', ['reusableModuleApp']); //Inject resuableModuleApp
in your application where you want to use toolbar component
mainApp.controller('mainAppController', function($scope){
$scope.value1 = "Add";
$scope.value2 = "Edit";
});
});
https://riptutorial.com/es/home 95
index.html:
<!doctype html>
<html ng-app="mainApp">
<head>
<title> Demo Making a reusable component
<head>
<body ng-controller="mainAppController">
<!-- We need to add the dependent js files on both apps here -->
<script src="js/angular.js"></script>
<script src="js/angular-sanitize.js"></script>
</body>
</html>
Las directivas son componentes reutilizables por defecto. Cuando hace directivas en un módulo
angular separado, en realidad lo hace exportable y reutilizable en diferentes aplicaciones
angulares. Las nuevas directivas simplemente se pueden agregar dentro de
reusableModuleApp.js y reusableModuleApp puede tener su propio controlador, servicios, objeto
DDO dentro de la directiva para definir el comportamiento.
La creación de una directiva personalizada con alcance aislado separará el alcance dentro de la
directiva del alcance externo , a fin de evitar que nuestra directiva cambie accidentalmente los
datos en el alcance principal y restrinja la lectura de datos privados del alcance principal.
Para crear un alcance aislado y aún permitir que nuestra directiva personalizada se comunique
con el alcance externo, podemos usar la opción de scope que describe cómo asignar los enlaces
del ámbito interno de la directiva con el alcance externo.
Los enlaces reales se realizan con atributos adicionales adjuntos a la directiva. Las
configuraciones de enlace se definen con la opción de scope y un objeto con pares clave-valor:
• Una clave , que se corresponde con la propiedad de alcance aislado de nuestra directiva.
https://riptutorial.com/es/home 96
scope: { // This is how we define an isolated scope
current: '=', // Create a REQUIRED bidirectional binding by using the 'current'
attribute
full: '=?maxValue' // Create an OPTIONAL (Note the '?'): bidirectional binding using
'max-value' attribute to the `full` property in our directive isolated scope
}
template: '<div class="progress-back">' +
' <div class="progress-bar"' +
' ng-style="{width: getProgress()}">' +
' </div>' +
'</div>',
link: function(scope, el, attrs) {
if (scope.full === undefined) {
scope.full = 100;
}
scope.getProgress = function() {
return (scope.current / scope.size * 100) + '%';
}
}
}
}
ProgressBar.$inject = [];
angular.module('app').directive('progressBar', ProgressBar);
Ejemplo de cómo usar esta directiva y vincular los datos del alcance del controlador al alcance
interno de la directiva:
Controlador:
angular.module('app').controller('myCtrl', function($scope) {
$scope.currentProgressValue = 39;
$scope.maxProgressBarValue = 50;
});
Ver:
<div ng-controller="myCtrl">
<progress-bar current="currentProgressValue"></progress-bar>
<progress-bar current="currentProgressValue" max-value="maxProgressBarValue"></progress-
bar>
</div>
Las directivas se pueden utilizar para construir componentes reutilizables. Aquí hay un ejemplo de
un componente de "carpeta de usuario":
userBox.js
https://riptutorial.com/es/home 97
},
templateUrl: '/path/to/app/directives/user-box.html'
};
});
Controller.js
myApp.controller('Controller', function($scope) {
$scope.user2 = "Andrew";
$scope.rep2 = 2850;
});
myPage.js
<body>
<div ng-controller="Controller">
<user-box username="user" reputation="rep"></user-box>
<user-box username="user2" reputation="rep2"></user-box>
</div>
</body>
</html>
user-box.html
<div>{{username}}</div>
<div>{{reputation}} reputation</div>
El resultado será:
John Doe
1250 reputation
Andrew
2850 reputation
Directivo decorador
https://riptutorial.com/es/home 98
El decorador será ejecutado durante la fase de inyección.
Para ello, provea un .config a su módulo. La directiva se llama myDirective, por lo que tiene que
configurar myDirectiveDirective. (esto en una convención angular [leer sobre proveedores]).
angular.module('myApp').config(function($provide){
$provide.decorator('myDirectiveDirective', function($delegate){
var directive = $delegate[0]; // this is the actual delegated, your directive
directive.templateUrl = 'newTemplate.html'; // you change the directive template
return $delegate;
})
});
Este ejemplo agrega un evento onClick al elemento directivo cuando se hace clic, esto sucede
durante la fase de compilación.
angular.module('myApp').config(function ($provide) {
$provide.decorator('myDirectiveTwoDirective', function ($delegate) {
var directive = $delegate[0];
var link = directive.link; // this is directive link phase
directive.compile = function () { // change the compile of that directive
return function (scope, element, attrs) {
link.apply(this, arguments); // apply this at the link phase
element.on('click', function(){ // when add an onclick that log hello when
the directive is clicked.
console.log('hello!');
});
};
};
return $delegate;
});
});
Se puede utilizar un enfoque similar tanto para los proveedores como para los servicios.
En este ejemplo, la directiva Adir expone a la directiva Bdir es su controlador $ scope, ya que Bdir
requiere Adir.
angular.module('myApp',[]).directive('Adir', function () {
return {
restrict: 'AE',
controller: ['$scope', function ($scope) {
$scope.logFn = function (val) {
console.log(val);
}
}]
}
})
https://riptutorial.com/es/home 99
Asegúrese de que los ajustes requieran: '^ Adir' (mire la documentación angular, algunas
versiones no requieren ^ carácter).
.directive('Bdir', function () {
return {
restrict: 'AE',
require: '^Adir', // Bdir require Adir
link: function (scope, elem, attr, Parent) {
// Parent is Adir but can be an array of required directives.
elem.on('click', function ($event) {
Parent.logFn("Hello!"); // will log "Hello! at parent dir scope
scope.$apply(); // apply to parent scope.
});
}
}
}]);
https://riptutorial.com/es/home 100
Capítulo 18: Directivas utilizando
ngModelController
Examples
Un control simple: calificación
Permítanos construir un control simple, un widget de calificación, destinado a ser utilizado como:
0 1 2 3 4 5 x
Al hacer clic en un número selecciona esa calificación; y al hacer clic en la "x" se establece la
calificación en nulo.
app.directive('rating', function() {
function RatingController() {
this._ngModel = null;
this.rating = null;
this.options = null;
this.min = typeof this.min === 'number' ? this.min : 1;
this.max = typeof this.max === 'number' ? this.max : 5;
}
RatingController.prototype.setNgModel = function(ngModel) {
this._ngModel = ngModel;
if( ngModel ) {
// KEY POINT 1
ngModel.$render = this._render.bind(this);
}
};
RatingController.prototype._render = function() {
this.rating = this._ngModel.$viewValue != null ? this._ngModel.$viewValue : -
Number.MAX_VALUE;
};
RatingController.prototype._calculateOptions = function() {
if( this.min == null || this.max == null ) {
this.options = [];
}
else {
this.options = new Array(this.max - this.min + 1);
for( var i=0; i < this.options.length; i++ ) {
this.options[i] = this.min + i;
}
}
https://riptutorial.com/es/home 101
};
RatingController.prototype.setValue = function(val) {
this.rating = val;
// KEY POINT 2
this._ngModel.$setViewValue(val);
};
// KEY POINT 3
Object.defineProperty(RatingController.prototype, 'min', {
get: function() {
return this._min;
},
set: function(val) {
this._min = val;
this._calculateOptions();
}
});
Object.defineProperty(RatingController.prototype, 'max', {
get: function() {
return this._max;
},
set: function(val) {
this._max = val;
this._calculateOptions();
}
});
return {
restrict: 'E',
scope: {
// KEY POINT 3
min: '<?',
max: '<?',
nullifier: '<?'
},
bindToController: true,
controllerAs: 'ctrl',
controller: RatingController,
require: ['rating', 'ngModel'],
link: function(scope, elem, attrs, ctrls) {
ctrls[0].setNgModel(ctrls[1]);
},
template:
'<span ng-repeat="o in ctrl.options" href="#" class="rating-option" ng-
class="{\'rating-option-active\': o <= ctrl.rating}" ng-click="ctrl.setValue(o)">{{ o
}}</span>' +
'<span ng-if="ctrl.nullifier" ng-click="ctrl.setValue(null)" class="rating-
nullifier">✖</span>'
};
});
Puntos clave:
https://riptutorial.com/es/home 102
vía. Si tiene que tomar medidas cada vez que cambia un parámetro, puede usar una
propiedad de JavaScript (consulte Object.defineProperty() ) para guardar algunos relojes.
Nota 2: Con la excepción de los enlaces de alcance '<' , este ejemplo se puede usar en Angular
<1.5. Si está en Angular> = 1.5, sería una buena idea transformar esto en un componente y usar
el gancho de ciclo de vida $onInit() para inicializar min y max , en lugar de hacerlo en el
constructor del controlador.
Un control personalizado no tiene que limitarse a cosas triviales como los primitivos; Puede editar
cosas más interesantes. Aquí presentamos dos tipos de controles personalizados, uno para editar
personas y otro para editar direcciones. El control de dirección se utiliza para editar la dirección
de la persona. Un ejemplo de uso sería:
<input-person ng-model="data.thePerson"></input-person>
<input-address ng-model="data.thePerson.address"></input-address>
function Person(data) {
data = data || {};
this.name = data.name;
this.address = data.address ? new Address(data.address) : null;
}
function Address(data) {
data = data || {};
this.street = data.street;
this.number = data.number;
}
El editor de direcciones:
app.directive('inputAddress', function() {
InputAddressController.$inject = ['$scope'];
function InputAddressController($scope) {
this.$scope = $scope;
this._ngModel = null;
this.value = null;
this._unwatch = angular.noop;
}
InputAddressController.prototype.setNgModel = function(ngModel) {
https://riptutorial.com/es/home 103
this._ngModel = ngModel;
if( ngModel ) {
// KEY POINT 3
ngModel.$render = this._render.bind(this);
}
};
InputAddressController.prototype._makeWatch = function() {
// KEY POINT 1
this._unwatch = this.$scope.$watchCollection(
(function() {
return this.value;
}).bind(this),
(function(newval, oldval) {
if( newval !== oldval ) { // skip the initial trigger
this._ngModel.$setViewValue(newval !== null ? new Address(newval) : null);
}
}).bind(this)
);
};
InputAddressController.prototype._render = function() {
// KEY POINT 2
this._unwatch();
this.value = this._ngModel.$viewValue ? new Address(this._ngModel.$viewValue) : null;
this._makeWatch();
};
return {
restrict: 'E',
scope: {},
bindToController: true,
controllerAs: 'ctrl',
controller: InputAddressController,
require: ['inputAddress', 'ngModel'],
link: function(scope, elem, attrs, ctrls) {
ctrls[0].setNgModel(ctrls[1]);
},
template:
'<div>' +
'<label><span>Street:</span><input type="text" ng-model="ctrl.value.street"
/></label>' +
'<label><span>Number:</span><input type="text" ng-model="ctrl.value.number"
/></label>' +
'</div>'
};
});
Puntos clave:
1. Estamos editando un objeto; no queremos cambiar directamente el objeto que nos entregó
nuestro padre (queremos que nuestro modelo sea compatible con el principio de
inmutabilidad). Así que creamos una observación superficial sobre el objeto que se está
editando y actualizamos el modelo con $setViewValue() cada vez que cambia una propiedad.
Pasamos una copia a nuestros padres.
2. Cuando el modelo cambia desde el exterior, lo copiamos y guardamos la copia en nuestro
alcance. De nuevo los principios de la inmutabilidad, aunque la copia interna no es
https://riptutorial.com/es/home 104
inmutable, la externa podría muy bien serlo. Además, reconstruimos el reloj (
this_unwatch();this._makeWatch(); ), para evitar activar al observador por los cambios que
nos presenta el modelo. (Solo queremos que el reloj se active por los cambios realizados en
la interfaz de usuario).
3. Aparte de los puntos anteriores, implementamos ngModel.$render() y llamamos
ngModel.$setViewValue() como lo haríamos con un control simple (consulte el ejemplo de
calificación).
El código para el control personalizado de la persona es casi idéntico. La plantilla está utilizando
la <input-address> . En una implementación más avanzada podríamos extraer los controladores en
un módulo reutilizable.
app.directive('inputPerson', function() {
InputPersonController.$inject = ['$scope'];
function InputPersonController($scope) {
this.$scope = $scope;
this._ngModel = null;
this.value = null;
this._unwatch = angular.noop;
}
InputPersonController.prototype.setNgModel = function(ngModel) {
this._ngModel = ngModel;
if( ngModel ) {
ngModel.$render = this._render.bind(this);
}
};
InputPersonController.prototype._makeWatch = function() {
this._unwatch = this.$scope.$watchCollection(
(function() {
return this.value;
}).bind(this),
(function(newval, oldval) {
if( newval !== oldval ) { // skip the initial trigger
this._ngModel.$setViewValue(newval !== null ? new Person(newval) : null);
}
}).bind(this)
);
};
InputPersonController.prototype._render = function() {
this._unwatch();
this.value = this._ngModel.$viewValue ? new Person(this._ngModel.$viewValue) : null;
this._makeWatch();
};
return {
restrict: 'E',
scope: {},
bindToController: true,
controllerAs: 'ctrl',
controller: InputPersonController,
require: ['inputPerson', 'ngModel'],
link: function(scope, elem, attrs, ctrls) {
ctrls[0].setNgModel(ctrls[1]);
https://riptutorial.com/es/home 105
},
template:
'<div>' +
'<label><span>Name:</span><input type="text" ng-model="ctrl.value.name"
/></label>' +
'<input-address ng-model="ctrl.value.address"></input-address>' +
'</div>'
};
});
Nota: aquí se escriben los objetos, es decir, tienen constructores adecuados. Esto no es
obligatorio; El modelo puede ser simple objetos JSON. En este caso, simplemente use
angular.copy() lugar de los constructores. Una ventaja adicional es que el controlador se vuelve
idéntico para los dos controles y se puede extraer fácilmente en algún módulo común.
El violín: https://jsfiddle.net/3tzyqfko/2/
Dos versiones del violín que extrajeron el código común de los controladores:
https://jsfiddle.net/agj4cp0e/ y https://jsfiddle.net/ugb6Lw8b/
https://riptutorial.com/es/home 106
Capítulo 19: El yo o esta variable en un
controlador
Introducción
Esta es una explicación de un patrón común y generalmente se considera la mejor práctica que
puede ver en el código de AngularJS.
Examples
Entender el propósito de la variable del uno mismo
Cuando use "controlador como sintaxis", le dará a su controlador un alias en el html cuando use
la directiva ng-controller.
Luego puede acceder a las propiedades y métodos desde la variable principal que representa
nuestra instancia de controlador. Por ejemplo, accedamos a la propiedad de saludo de nuestro
controlador y la mostremos en la pantalla:
angular
.module('ngNjOrg')
.controller('ForgotPasswordController',function ($log) {
var self = this;
Con el fin de tener la pantalla HTML correctamente que necesitamos para establecer la propiedad
de felicitación en esto dentro de nuestro cuerpo del controlador. Estoy creando una variable
intermedia llamada self que contiene una referencia a esto. ¿Por qué? Considere este código:
angular
.module('ngNjOrg')
.controller('ForgotPasswordController',function ($log) {
var self = this;
https://riptutorial.com/es/home 107
self.greeting = "Hello World";
function itsLate () {
this.greeting = "Goodnight";
}
})
En este código anterior, puede esperar que el texto en la pantalla se actualice cuando se llame al
método ItsLate , pero en realidad no lo hace. JavaScript usa las reglas de alcance del nivel de
función, por lo que "esto" dentro de su estado actual se refiere a algo diferente que "esto" fuera
del cuerpo del método. Sin embargo, podemos obtener el resultado deseado si usamos la propia
variable:
angular
.module('ngNjOrg')
.controller('ForgotPasswordController',function ($log) {
var self = this;
function itsLate () {
self.greeting = "Goodnight";
}
})
Esta es la belleza de usar una variable "propia" en sus controladores: puede acceder a esta
desde cualquier parte de su controlador y siempre puede estar seguro de que hace referencia a
su instancia de controlador.
https://riptutorial.com/es/home 108
Capítulo 20: enrutador ui
Observaciones
¿Qué es ui-router ?
Los marcos de enrutamiento para SPA actualizan la URL del navegador a medida que
el usuario navega a través de la aplicación. A la inversa, esto permite cambios en la
URL del navegador para conducir la navegación a través de la aplicación, lo que
permite al usuario crear un marcador en una ubicación dentro del SPA.
Enlaces útiles
Puedes encontrar la documentación oficial de la API aquí . Si tiene preguntas sobre ui-router VS
ng-router , puede encontrar una respuesta razonablemente detallada aquí . Tenga en cuenta que
ng-router ya ha lanzado una nueva actualización de ng-router llamada ngNewRouter (compatible
con Angular 1.5 + / 2.0) que admite estados como ui-router. Puedes leer más sobre ngNewRouter
aquí .
Examples
Ejemplo básico
app.js
angular.module('myApp', ['ui.router'])
.controller('controllerOne', function() {
this.message = 'Hello world from Controller One!';
})
.controller('controllerTwo', function() {
this.message = 'Hello world from Controller Two!';
})
.controller('controllerThree', function() {
this.message = 'Hello world from Controller Three!';
})
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('one', {
url: "/one",
templateUrl: "view-one.html",
controller: 'controllerOne',
controllerAs: 'ctrlOne'
https://riptutorial.com/es/home 109
})
.state('two', {
url: "/two",
templateUrl: "view-two.html",
controller: 'controllerTwo',
controllerAs: 'ctrlTwo'
})
.state('three', {
url: "/three",
templateUrl: "view-three.html",
controller: 'controllerThree',
controllerAs: 'ctrlThree'
});
$urlRouterProvider.otherwise('/one');
});
index.html
<div ng-app="myApp">
<nav>
<!-- links to switch routes -->
<a ui-sref="one">View One</a>
<a ui-sref="two">View Two</a>
<a ui-sref="three">View Three</a>
</nav>
<!-- views will be injected here -->
<div ui-view></div>
<!-- templates can live in normal html files -->
<script type="text/ng-template" id="view-one.html">
<h1>{{ctrlOne.message}}</h1>
</script>
Vistas múltiples
app.js
angular.module('myApp', ['ui.router'])
.controller('controllerOne', function() {
this.message = 'Hello world from Controller One!';
})
.controller('controllerTwo', function() {
this.message = 'Hello world from Controller Two!';
})
.controller('controllerThree', function() {
this.message = 'Hello world from Controller Three!';
})
.controller('controllerFour', function() {
this.message = 'Hello world from Controller Four!';
https://riptutorial.com/es/home 110
})
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('one', {
url: "/one",
views: {
"viewA": {
templateUrl: "view-one.html",
controller: 'controllerOne',
controllerAs: 'ctrlOne'
},
"viewB": {
templateUrl: "view-two.html",
controller: 'controllerTwo',
controllerAs: 'ctrlTwo'
}
}
})
.state('two', {
url: "/two",
views: {
"viewA": {
templateUrl: "view-three.html",
controller: 'controllerThree',
controllerAs: 'ctrlThree'
},
"viewB": {
templateUrl: "view-four.html",
controller: 'controllerFour',
controllerAs: 'ctrlFour'
}
}
});
$urlRouterProvider.otherwise('/one');
});
index.html
<div ng-app="myApp">
<nav>
<!-- links to switch routes -->
<a ui-sref="one">Route One</a>
<a ui-sref="two">Route Two</a>
</nav>
<!-- views will be injected here -->
<div ui-view="viewA"></div>
<div ui-view="viewB"></div>
<!-- templates can live in normal html files -->
<script type="text/ng-template" id="view-one.html">
<h1>{{ctrlOne.message}}</h1>
</script>
https://riptutorial.com/es/home 111
<script type="text/ng-template" id="view-four.html">
<h1>{{ctrlFour.message}}</h1>
</script>
</div>
app.js
angular.module('myApp', ['ui.router'])
.service('User', ['$http', function User ($http) {
this.getProfile = function (id) {
return $http.get(...) // method to load data from API
};
}])
.controller('profileCtrl', ['profile', function profileCtrl (profile) {
// inject resolved data under the name of the resolve function
// data will already be returned and processed
this.profile = profile;
}])
.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider,
$urlRouterProvider) {
$stateProvider
.state('profile', {
url: "/profile/:userId",
templateUrl: "profile.html",
controller: 'profileCtrl',
controllerAs: 'vm',
resolve: {
profile: ['$stateParams', 'User', function ($stateParams, User) {
// $stateParams will contain any parameter defined in your url
return User.getProfile($stateParams.userId)
// .then is only necessary if you need to process returned data
.then(function (data) {
return doSomeProcessing(data);
});
}]
}
}]);
$urlRouterProvider.otherwise('/');
});
profile.html
<ul>
<li>Name: {{vm.profile.name}}</li>
<li>Age: {{vm.profile.age}}</li>
<li>Sex: {{vm.profile.sex}}</li>
</ul>
https://riptutorial.com/es/home 112
resolución en el estado hayan finalizado. Esta es una excelente manera de asegurar que los
datos estén disponibles para su controlador y su interfaz de usuario. Sin embargo, puede ver que
una función de resolución debe ser rápida para evitar bloquear la interfaz de usuario.
app.js
app.config(function($stateProvider,$urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'home.html',
controller: function($scope){
$scope.text = 'This is the Home'
}
})
.state('home.nested1',{
url: '/nested1',
templateUrl:'nested1.html',
controller: function($scope){
$scope.text1 = 'This is the nested view 1'
}
})
.state('home.nested2',{
url: '/nested2',
templateUrl:'nested2.html',
controller: function($scope){
$scope.fruits = ['apple','mango','oranges'];
}
});
$urlRouterProvider.otherwise('/home');
});
index.html
<div ui-view></div>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="angular-ui-router.min.js"></script>
<script src="app.js"></script>
home.html
<div>
<h1> {{text}} </h1>
<br>
<a ui-sref="home.nested1">Show nested1</a>
https://riptutorial.com/es/home 113
<br>
<a ui-sref="home.nested2">Show nested2</a>
<br>
<div ui-view></div>
</div>
nested1.html
<div>
<h1> {{text1}} </h1>
</div>
nested2.html
<div>
<ul>
<li ng-repeat="fruit in fruits">{{ fruit }}</li>
</ul>
</div>
https://riptutorial.com/es/home 114
Capítulo 21: Enrutamiento usando ngRoute
Observaciones
El ngRoute es un módulo incorporado que proporciona directivas y servicios de enrutamiento y
deeplinking para aplicaciones angulares.
Examples
Ejemplo basico
Este ejemplo muestra la configuración de una pequeña aplicación con 3 rutas, cada una con su
propia vista y controlador, utilizando la sintaxis del controllerAs .
1. $routeProvider en .config
2. Definimos nuestros nombres de ruta en el método .when con un objeto de definición de ruta.
3. Suministramos al método .when con un objeto que especifica nuestra template o templateUrl ,
controller y controllerAs
app.js
angular.module('myApp', ['ngRoute'])
.controller('controllerOne', function() {
this.message = 'Hello world from Controller One!';
})
.controller('controllerTwo', function() {
this.message = 'Hello world from Controller Two!';
})
.controller('controllerThree', function() {
this.message = 'Hello world from Controller Three!';
})
.config(function($routeProvider) {
$routeProvider
.when('/one', {
templateUrl: 'view-one.html',
controller: 'controllerOne',
controllerAs: 'ctrlOne'
})
.when('/two', {
templateUrl: 'view-two.html',
controller: 'controllerTwo',
controllerAs: 'ctrlTwo'
})
.when('/three', {
templateUrl: 'view-three.html',
controller: 'controllerThree',
https://riptutorial.com/es/home 115
controllerAs: 'ctrlThree'
})
// redirect to here if no other routes match
.otherwise({
redirectTo: '/one'
});
});
Luego, en nuestro HTML definimos nuestra navegación usando <a> elementos con href , para un
nombre de ruta de helloRoute lo haremos como <a href="#/helloRoute">My route</a>
También proporcionamos nuestra vista con un contenedor y la directiva ng-view para inyectar
nuestras rutas.
index.html
<div ng-app="myApp">
<nav>
<!-- links to switch routes -->
<a href="#/one">View One</a>
<a href="#/two">View Two</a>
<a href="#/three">View Three</a>
</nav>
<!-- views will be injected here -->
<div ng-view></div>
<!-- templates can live in normal html files -->
<script type="text/ng-template" id="view-one.html">
<h1>{{ctrlOne.message}}</h1>
</script>
Este ejemplo amplía el ejemplo básico pasando parámetros en la ruta para usarlos en el
controlador
app.js
angular.module('myApp', ['ngRoute'])
.controller('controllerOne', function() {
this.message = 'Hello world from Controller One!';
})
https://riptutorial.com/es/home 116
.controller('controllerTwo', function() {
this.message = 'Hello world from Controller Two!';
})
.controller('controllerThree', ['$routeParams', function($routeParams) {
var routeParam = $routeParams.paramName
if ($routeParams.message) {
// If a param called 'message' exists, we show it's value as the message
this.message = $routeParams.message;
} else {
// If it doesn't exist, we show a default message
this.message = 'Hello world from Controller Three!';
}
}])
.config(function($routeProvider) {
$routeProvider
.when('/one', {
templateUrl: 'view-one.html',
controller: 'controllerOne',
controllerAs: 'ctrlOne'
})
.when('/two', {
templateUrl: 'view-two.html',
controller: 'controllerTwo',
controllerAs: 'ctrlTwo'
})
.when('/three', {
templateUrl: 'view-three.html',
controller: 'controllerThree',
controllerAs: 'ctrlThree'
})
.when('/three/:message', { // We will pass a param called 'message' with this route
templateUrl: 'view-three.html',
controller: 'controllerThree',
controllerAs: 'ctrlThree'
})
// redirect to here if no other routes match
.otherwise({
redirectTo: '/one'
});
});
Luego, sin hacer ningún cambio en nuestras plantillas, solo agregando un nuevo enlace con un
mensaje personalizado, podemos ver el nuevo mensaje personalizado en nuestra vista.
index.html
<div ng-app="myApp">
<nav>
<!-- links to switch routes -->
<a href="#/one">View One</a>
<a href="#/two">View Two</a>
<a href="#/three">View Three</a>
<!-- New link with custom message -->
<a href="#/three/This-is-a-message">View Three with "This-is-a-message" custom message</a>
</nav>
<!-- views will be injected here -->
<div ng-view></div>
<!-- templates can live in normal html files -->
https://riptutorial.com/es/home 117
<script type="text/ng-template" id="view-one.html">
<h1>{{ctrlOne.message}}</h1>
</script>
La forma más sencilla de definir el comportamiento personalizado para rutas individuales sería
bastante fácil.
1) routes.js : crea una nueva propiedad (como requireAuth ) para cualquier ruta deseada
angular.module('yourApp').config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/home', {
templateUrl: 'templates/home.html',
requireAuth: true
})
.when('/login', {
templateUrl: 'templates/login.html',
})
.otherwise({
redirectTo: '/home'
});
}])
});
}
]);
https://riptutorial.com/es/home 118
https://riptutorial.com/es/angularjs/topic/2391/enrutamiento-usando-ngroute
https://riptutorial.com/es/home 119
Capítulo 22: estilo ng
Introducción
La directiva 'ngStyle' le permite establecer el estilo CSS en un elemento HTML condicionalmente.
Al igual que la forma en que podríamos usar el atributo de estilo en un elemento HTML en
proyectos que no son AngularJS, podemos usar ng-style en angularjs para aplicar estilos
basados en alguna condición booleana.
Sintaxis
• <ANY ng-style="expression"></ANY >
Examples
Uso de estilo ng
https://riptutorial.com/es/home 120
Capítulo 23: Eventos
Parámetros
args Datos que se han pasado junto con la ejecución del evento.
Examples
Utilizando sistema de eventos angulares.
$ scope. $ emit
El uso de $scope.$emit disparará un nombre de evento hacia arriba a través de la jerarquía de
alcance y notificará a $scope . El ciclo de vida del evento comienza en el ámbito en el que se llamó
a $emit .
Wireframe de trabajo:
https://riptutorial.com/es/home 121
$ scope. $ broadcast
El uso de $scope.$broadcast desencadenará un evento en $scope . Podemos escuchar estos
eventos usando $scope.$on
Wireframe de trabajo:
Sintaxis:
// firing an event upwards
$scope.$emit('myCustomEvent', 'Data to send');
En lugar de $scope , puede usar $rootScope , en ese caso, su evento estará disponible en todos los
controladores, independientemente del alcance de los controladores.
https://riptutorial.com/es/home 122
El motivo para limpiar los eventos registrados, ya que incluso el controlador ha sido destruido, el
manejo del evento registrado sigue vivo. Así que el código se ejecutará como inesperado seguro.
// listening an event
var listenerEventHandler = $rootScope.$on('myEvent', function(){
//handle code
});
$scope.$on('$destroy', function() {
listenerEventHandler();
});
Usos y significado
$emitenvía un evento hacia arriba a través de la jerarquía de alcance, mientras que $broadcast
envía un evento hacia abajo a todos los ámbitos secundarios. Esto se ha explicado muy bien aquí
.
Básicamente, puede haber dos tipos de escenarios mientras se comunican entre los
controladores:
1. Cuando los controladores tienen relación padre-hijo. (En su mayoría, podemos usar $scope
en tales escenarios)
2. Cuando los controladores no son independientes entre sí y son necesarios para estar
informados sobre la actividad de cada uno. (Podemos usar $rootScope en tales escenarios)
por ejemplo: para cualquier sitio web de comercio electrónico, supongamos que tenemos
ProductListController (que controla la página de listado de productos cuando se hace clic en
cualquier marca del producto) y CartController (para administrar los artículos del carrito). Ahora,
cuando hacemos clic en el botón Agregar al carrito , también se debe informar a CartController ,
para que pueda reflejar el nuevo recuento de artículos del carrito / detalles en la barra de
navegación del sitio web. Esto se puede lograr usando $rootScope .
Con $scope.$emit
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script>
<script>
var app = angular.module('app', []);
https://riptutorial.com/es/home 123
$scope.message = args.message;
});
});
</script>
</head>
<body ng-app="app">
<div ng-controller="FirstController" style="border:2px ;padding:5px;">
<h1>Parent Controller</h1>
<p>Emit Message : {{message}}</p>
<br />
<div ng-controller="SecondController" style="border:2px;padding:5px;">
<h1>Child Controller</h1>
<input ng-model="msg">
<button ng-click="handleClick(msg);">Emit</button>
</div>
</div>
</body>
</html>
Con $scope.$broadcast :
<html>
<head>
<title>Broadcasting</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script>
<script>
var app = angular.module('app', []);
});
</script>
</head>
<body ng-app="app">
<div ng-controller="FirstController" style="border:2px solid ; padding:5px;">
<h1>Parent Controller</h1>
<input ng-model="msg">
<button ng-click="handleClick(msg);">Broadcast</button>
<br /><br />
<div ng-controller="SecondController" style="border:2px solid ;padding:5px;">
<h1>Child Controller</h1>
<p>Broadcast Message : {{message}}</p>
</div>
https://riptutorial.com/es/home 124
</div>
</body>
</html>
No hacer
angular.module('app').controller('badExampleController', badExample);
Hacer
angular.module('app').controller('goodExampleController', goodExample);
https://riptutorial.com/es/home 125
Capítulo 24: Filtros
Examples
Su primer filtro
Los filtros son un tipo especial de función que puede modificar la forma en que se imprime algo en
la página, o se puede usar para filtrar una matriz o una acción de ng-repeat . Puede crear un filtro
llamando al método app.filter() , pasándole un nombre y una función. Vea los ejemplos a
continuación para detalles sobre la sintaxis.
Por ejemplo, vamos a crear un filtro que cambiará una cadena a mayúsculas (esencialmente un
contenedor de la función javascript .toUpperCase() ):
Nota: En esta situación, asumimos que el objeto que se pasa al filtro es una cadena y, por lo
tanto, sabemos que siempre se debe usar el filtro solo en las cadenas. Dicho esto, se podría
realizar una mejora adicional en el filtro que recorre el objeto (si es una matriz) y luego hace que
cada elemento sea una cadena en mayúscula.
Ahora vamos a usar nuestro nuevo filtro en acción. Nuestro filtro se puede utilizar de dos
maneras, ya sea en una plantilla angular o como una función javascript (como referencia angular
inyectada).
Javascript
Simplemente inyecte el objeto $filter angular en su controlador, luego úselo para recuperar la
https://riptutorial.com/es/home 126
función de filtro usando su nombre.
HTML
Para una directiva angular, use el símbolo de la tubería ( | ) seguido del nombre del filtro en la
directiva después de la cadena real. Por ejemplo, digamos que tenemos un controlador llamado
MyController que tiene una cadena llamada rawString como un elemento de ella.
Nota del editor: Angular tiene una serie de filtros incorporados, que incluyen "mayúsculas", y el
filtro "a mayúsculas" está pensado solo como una demostración para mostrar fácilmente cómo
funcionan los filtros, pero no necesita crear su propia función de mayúsculas.
Un caso de uso típico de un filtro es eliminar valores de una matriz. En este ejemplo, pasamos
una matriz y eliminamos cualquier nulo que se encuentre en ella, devolviendo la matriz.
function removeNulls() {
return function(list) {
for (var i = list.length - 1; i >= 0; i--) {
if (typeof list[i] === 'undefined' ||
list[i] === null) {
list.splice(i, 1);
}
}
return list;
};
}
{{listOfItems | removeNulls}}
o en un controlador como
listOfItems = removeNullsFilter(listOfItems);
Otro caso de uso para los filtros es dar formato a un solo valor. En este ejemplo, pasamos un
https://riptutorial.com/es/home 127
valor y se nos devuelve un valor booleano verdadero apropiado.
function convertToBooleanValue() {
return function(input) {
if (typeof input !== 'undefined' &&
input !== null &&
(input === true || input === 1 || input === '1' || input
.toString().toLowerCase() === 'true')) {
return true;
}
return false;
};
}
{{isAvailable | convertToBooleanValue}}
O en un controlador como:
Este ejemplo se realizó para demostrar cómo puede realizar un filtro profundo en una matriz
secundaria sin la necesidad de un filtro personalizado.
Controlador:
(function() {
"use strict";
angular
.module('app', [])
.controller('mainCtrl', mainCtrl);
function mainCtrl() {
var vm = this;
https://riptutorial.com/es/home 128
"name":"Saloons"
},
{
"name":"Commercial vehicle"
}
]
},
{
"name":"car3",
"classifications":[
{
"name":"Sport car"
},
{
"name":"Sedans"
}
]
}
];
}
})();
Ver:
Al inyectar $filter , cualquier filtro definido en su módulo Angular puede usarse en controladores,
servicios, directivas o incluso en otros filtros.
angular.module("app")
.service("users", usersService)
.controller("UsersController", UsersController);
function usersService () {
this.getAll = function () {
return [{
id: 1,
username: "john"
}, {
id: 2,
username: "will"
}, {
https://riptutorial.com/es/home 129
id: 3,
username: "jack"
}];
};
}
Ocasionalmente, querrá acceder al resultado de sus filtros desde fuera de la ng-repeat , tal vez
para indicar el número de elementos que se han filtrado. Puede hacer esto usando as
[variablename] sintaxis as [variablename] en la ng-repeat .
<ul>
<li ng-repeat="item in vm.listItems | filter:vm.myFilter as filtered">
{{item.name}}
</li>
</ul>
<span>Showing {{filtered.length}} of {{vm.listItems.length}}</span>
https://riptutorial.com/es/home 130
Capítulo 25: Filtros personalizados
Examples
Ejemplo de filtro simple
Los filtros formatean el valor de una expresión para mostrarla al usuario. Se pueden utilizar en
plantillas de vista, controladores o servicios. Este ejemplo crea un filtro ( addZ ) y luego lo usa en
una vista. Todo lo que hace este filtro es agregar una 'Z' mayúscula al final de la cadena.
example.js
angular.module('main', [])
.filter('addZ', function() {
return function(value) {
return value + "Z";
}
})
.controller('MyController', ['$scope', function($scope) {
$scope.sample = "hello";
}])
example.html
Dentro de la vista, el filtro se aplica con la siguiente sintaxis: { variable | filter} . En este caso,
la variable que definimos en el controlador, sample , se filtra por el filtro que creamos, addZ .
<div ng-controller="MyController">
<span>{{sample | addZ}}</span>
</div>
Rendimiento esperado
helloZ
angular
.module('filters', [])
.filter('percentage', function($filter) {
return function (input) {
return $filter('number')(input * 100) + ' %';
};
});
https://riptutorial.com/es/home 131
Crear un filtro con parámetros.
Por defecto, un filtro tiene un solo parámetro: la variable sobre la que se aplica. Pero puedes
pasar más parámetros a la función:
angular
.module('app', [])
.controller('MyController', function($scope) {
$scope.example = 0.098152;
})
.filter('percentage', function($filter) {
return function (input, decimals) {
return $filter('number')(input * 100, decimals) + ' %';
};
});
... pero otros parámetros son opcionales, aún puede usar el filtro predeterminado:
https://riptutorial.com/es/home 132
Capítulo 26: Filtros personalizados con ES6
Examples
Filtro de tamaño de archivo usando ES6
Aquí tenemos un filtro de tamaño de archivo para describir cómo agregar un filtro de costo a un
módulo existente:
let fileSizeFilter=function () {
return function (size) {
if (isNaN(size))
size = 0;
size /= 1024;
size /= 1024;
size /= 1024;
size /= 1024;
return fileSize(size,'To',2);
};
};
export default fileSizeFilter;
<div ng-app="mainApp">
https://riptutorial.com/es/home 133
<div>
<input type="text" ng-model="size" />
</div>
<div>
<h3>Output:</h3>
<p>{{size| Filesize}}</p>
</div>
</div>
https://riptutorial.com/es/home 134
Capítulo 27: Funciones auxiliares
incorporadas
Examples
angular.equals
Esta función es útil cuando necesita comparar en profundidad objetos o matrices por sus valores
o resultados en lugar de solo referencias.
Ejemplos
angular.equals(1, 1) // true
angular.equals(1, 2) // false
angular.equals({}, {}) // true, note that {}==={} is false
angular.equals({a: 1}, {a: 1}) // true
angular.equals({a: 1}, {a: 2}) // false
angular.equals(NaN, NaN) // true
angular.isString
La función angular.isString devuelve verdadero si el objeto o valor que se le asigna es del tipo
string
angular.isString (valor1)
Ejemplos
angular.isString("hello") // true
angular.isString([1, 2]) // false
angular.isString(42) // false
https://riptutorial.com/es/home 135
angular.isArray
La función angular.isArray devuelve verdadero si y solo si el objeto o valor que se le pasa es del
tipo Array .
angular.isArray (valor)
Ejemplos
angular.isArray([]) // true
angular.isArray([2, 3]) // true
angular.isArray({}) // false
angular.isArray(17) // false
Es el equivalente de
Array.isArray(someValue)
angular.merge
La función angular.merge toma todas las propiedades enumerables del objeto de origen para
extender profundamente el objeto de destino.
Ejemplos
angular.merge({}, {}) // {}
angular.merge({name: "king roland"}, {password: "12345"})
// {name: "king roland", password: "12345"}
angular.merge({a: 1}, [4, 5, 6]) // {0: 4, 1: 5, 2: 6, a: 1}
angular.merge({a: 1}, {b: {c: {d: 2}}}) // {"a":1,"b":{"c":{"d":2}}}
angular.isDefinido y angular.isUndefined
angular.isDefined (someValue)
Ejemplos
angular.isDefined(42) // true
angular.isDefined([1, 2]) // true
angular.isDefined(undefined) // false
https://riptutorial.com/es/home 136
angular.isDefined(null) // true
angular.isUndefined (someValue)
O solo
!angular.isDefined(value)
Ejemplos
angular.isUndefined(42) // false
angular.isUndefined(undefined) // true
angular.isfecha
La función angular.isDate devuelve verdadero si y solo si el objeto que se le pasa es del tipo
Fecha.
angular.isDate (valor)
Ejemplos
angular.isNumber
La función angular.isNumber devuelve verdadero si y solo si el objeto o valor que se le pasa es del
tipo Número, esto incluye + Infinito, -Infinito y NaN
angular.isNumber (valor)
"23" == 23 // true
Ejemplos
angular.isNumber("23") // false
angular.isNumber(23) // true
angular.isNumber(NaN) // true
https://riptutorial.com/es/home 137
angular.isNumber(Infinity) // true
"23" == 23 // true
angular.isFunción
angular.isFunción (fn)
Ejemplos
angular.toJson
La función angular.toJson tomará un objeto y lo serializará en una cadena con formato JSON.
A diferencia de la función nativa JSON.stringify , esta función eliminará todas las propiedades que
comienzan con $$ (como angular generalmente prefijos propiedades internas con $$ )
angular.toJson(object)
Como los datos deben ser serializados antes de pasar a través de una red, esta función es útil
para convertir cualquier información que desee transmitir en JSON.
Esta función también es útil para la depuración, ya que funciona de manera similar a como lo
.toString un método .toString .
Ejemplos:
https://riptutorial.com/es/home 138
angular.fromJson
La función angular.fromJson deserializará una cadena JSON válida y devolverá un objeto o una
matriz.
Tenga en cuenta que esta función no se limita a solo cadenas, generará una representación de
cualquier objeto que se le pase.
Ejemplos:
angular.fromJson("{\"yogurt\": \"strawberries\"}")
// Object {yogurt: "strawberries"}
angular.fromJson('{jam: "raspberries"}')
// will throw an exception as the string is not a valid JSON
angular.fromJson(this)
// Window {external: Object, chrome: Object, _gaq: Y, angular: Object, ng339: 3…}
angular.fromJson([1, 2])
// [1, 2]
typeof angular.fromJson(new Date())
// "object"
angular.noop
angular.noopes una función que no realiza ninguna operación, usted pasa angular.noop cuando
necesita proporcionar un argumento de función que no hará nada.
angular.noop ()
Un uso común de angular.noop puede ser proporcionar una devolución de llamada vacía a una
función que, de lo contrario, generará un error cuando se le pase algo que no sea una función.
Ejemplo:
Ejemplos adicionales:
angular.noop() // undefined
angular.isFunction(angular.noop) // true
https://riptutorial.com/es/home 139
angular.isObjeto
angular.isObjeto (valor)
Esta función es útil para la verificación de tipos cuando necesita procesar un objeto definido.
Ejemplos:
angular.iselemento
angular.isElemento (elem)
Esta función es útil para escribir check si un argumento pasado es un elemento antes de ser
procesado como tal.
Ejemplos:
angular.isElement(document.querySelector("body"))
// true
angular.isElement(document.querySelector("#some_id"))
// false if "some_id" is not using as an id inside the selected DOM
angular.isElement("<div></div>")
// false
angular.copy
La función angular.copy toma un objeto, una matriz o un valor y crea una copia profunda de él.
angular.copy ()
Ejemplo:
Objetos:
https://riptutorial.com/es/home 140
let obj = {name: "vespa", occupation: "princess"};
let cpy = angular.copy(obj);
cpy.name = "yogurt"
// obj = {name: "vespa", occupation: "princess"}
// cpy = {name: "yogurt", occupation: "princess"}
Arrays:
identidad angular
Esta función es útil para la programación funcional, puede proporcionar esta función como
predeterminada en caso de que no se haya pasado una función esperada.
Ejemplos:
angular.identity(42) // 42
angular.para cada
Ejemplos:
https://riptutorial.com/es/home 141
angular.forEach({"a": 12, "b": 34}, (value, key) => console.log("key: " + key + ", value: " +
value))
// key: a, value: 12
// key: b, value: 34
angular.forEach([2, 4, 6, 8, 10], (value, key) => console.log(key))
// will print the array indices: 1, 2, 3, 4, 5
angular.forEach([2, 4, 6, 8, 10], (value, key) => console.log(value))
// will print the array values: 2, 4, 6, 7, 10
angular.forEach(undefined, (value, key) => console.log("key: " + key + ", value: " + value))
// undefined
https://riptutorial.com/es/home 142
Capítulo 28: Impresión
Observaciones
Crear una clase ng-hide en el archivo css. ng-show / hide no funcionará sin la clase.
Más detalles
Examples
Servicio de impresión
Servicio:
hiddenFrame.contentWindow.printAndRemove = function() {
hiddenFrame.contentWindow.print();
$(hiddenFrame).remove();
deferred.resolve();
};
$rootScope.isBeingPrinted = true;
https://riptutorial.com/es/home 143
$http.get(templateUrl).success(function(template){
var printScope = $rootScope.$new()
angular.extend(printScope, data);
var element = $compile($('<div>' + template + '</div>'))(printScope);
var waitForRenderAndPrint = function() {
if(printScope.$$phase || $http.pendingRequests.length) {
$timeout(waitForRenderAndPrint, 1000);
} else {
// Replace printHtml with openNewWindow for debugging
printHtml(element.html());
printScope.$destroy();
}
};
waitForRenderAndPrint();
});
};
return {
print : print,
printFromScope : printFromScope
}
}
]);
Controlador :
https://riptutorial.com/es/home 144
Capítulo 29: Interceptor HTTP
Introducción
El servicio $ http de AngularJS nos permite comunicarnos con un backend y realizar solicitudes
HTTP. Hay casos en los que queremos capturar cada solicitud y manipularla antes de enviarla al
servidor. Otras veces nos gustaría capturar la respuesta y procesarla antes de completar la
llamada. El manejo global de errores de http puede ser también un buen ejemplo de tal
necesidad. Los interceptores son creados exactamente para tales casos.
Examples
Empezando
El servicio $http integrado de Angular nos permite enviar solicitudes HTTP. Con frecuencia, surge
la necesidad de hacer cosas antes o después de una solicitud, por ejemplo, agregar a cada
solicitud un token de autenticación o crear una lógica genérica de manejo de errores.
<!DOCTYPE html>
<html>
<head>
<title>Angular Interceptor Sample</title>
<script src="https://code.angularjs.org/1.5.8/angular.min.js"></script>
<script src="app.js"></script>
<script src="appController.js"></script>
<script src="genericInterceptor.js"></script>
</head>
<body ng-app="interceptorApp">
<div ng-controller="appController as vm">
<button ng-click="vm.sendRequest()">Send a request</button>
</div>
</body>
</html>
interceptorApp.config(function($httpProvider) {
$httpProvider.interceptors.push('genericInterceptor');
});
(function() {
https://riptutorial.com/es/home 145
'use strict';
function appController($http) {
var vm = this;
vm.sendRequest = function(){
$http.get('http://google.com').then(function(response){
console.log(response);
});
};
}
angular.module('interceptorApp').controller('appController',['$http', appController]);
})();
(function() {
"use strict";
function genericInterceptor($q) {
this.responseError = function (response) {
return $q.reject(response);
};
this.requestError = function(request){
if (canRecover(rejection)) {
return responseOrNewPromise
}
return $q.reject(rejection);
};
this.response = function(response){
return response;
};
this.request = function(config){
return config;
}
}
angular.module('interceptorApp').service('genericInterceptor', genericInterceptor);
})();
En el archivo de vista
En el html base (index.html) donde usualmente incluimos los scripts angulares o el html que se
comparte en la aplicación, dejamos un elemento div vacío, los mensajes flash aparecerán dentro
de este elemento div
https://riptutorial.com/es/home 146
<div class="flashmessage" ng-if="isVisible">
{{flashMessage}}
</div>
Archivo de comandos
En el método de configuración del módulo angular, inyecte el httpProvider, el httpProvider tiene
una propiedad de matriz de interceptor, presione el interceptor personalizado. En el ejemplo
actual, el interceptor personalizado solo intercepta la respuesta y llama a un método asociado a
rootScope.
interceptorTest.config(['$httpProvider',function ($httpProvider) {
$httpProvider.interceptors.push(["$rootScope",function ($rootScope) {
return { //intercept only the response
'response': function (response)
{
$rootScope.showFeedBack(response.status,response.data.message);
return response;
}
};
}]);
}])
Dado que solo los proveedores pueden ser inyectados en el método de configuración de un
módulo angular (es decir, httpProvider y no en el de rootscope), declare el método conectado al
rootscope dentro del método de ejecución del módulo angular.
También muestre el mensaje dentro de $ timeout para que el mensaje tenga la propiedad flash,
que está desapareciendo después de un tiempo límite. En nuestro ejemplo sus 3000 ms.
interceptorTest.run(["$rootScope","$timeout",function($rootScope,$timeout){
$rootScope.showFeedBack = function(status,message){
$rootScope.isVisible = true;
$rootScope.flashMessage = message;
$timeout(function(){$rootScope.isVisible = false },3000)
}
}]);
Errores comunes
Al intentar inyectar $ rootScope o cualquier otro servicio dentro del método de configuración
del módulo angular, el ciclo de vida de la aplicación angular no permite eso y se generará un error
de proveedor desconocido. Solo los proveedores pueden ser inyectados en el método de
configuración del módulo angular.
https://riptutorial.com/es/home 147
Lea Interceptor HTTP en línea: https://riptutorial.com/es/angularjs/topic/6484/interceptor-http
https://riptutorial.com/es/home 148
Capítulo 30: Inyección de dependencia
Sintaxis
• myApp.controller ('MyController', function ($ scope) {...}); // código no minificado
• función MyController () {}
Observaciones
Los proveedores no pueden ser inyectados en bloques de run .
Examples
Inyecciones
El ejemplo más simple de una inyección en una aplicación Angular: inyectar $scope a un
Controller Angular:
angular.module('myModule', [])
.controller('myController', ['$scope', function($scope) {
$scope.members = ['Alice', 'Bob'];
...
}])
El sistema de Angular se encarga de resolver las dependencias por usted. Si crea un servicio, por
ejemplo, puede listarlo como en el ejemplo anterior y estará disponible para usted.
Puede usar DI - inyección de dependencia, donde quiera que esté definiendo un componente.
Tenga en cuenta que en el ejemplo anterior usamos lo que se denomina "Anotación de matriz en
https://riptutorial.com/es/home 149
línea". Es decir, escribimos explícitamente como cadenas los nombres de nuestras dependencias.
Lo hacemos para evitar que la aplicación se rompa cuando el código se minimiza para
Producción. La reducción de código cambia los nombres de las variables (pero no de las
cadenas), lo que rompe la inyección. Mediante el uso de cadenas, Angular sabe qué
dependencias queremos.
Muy importante: el orden de los nombres de las cadenas debe ser el mismo que el de los
parámetros en la función.
Existen herramientas que automatizan este proceso y se encargan de esto por usted.
Inyecciones dinamicas
También hay una opción para solicitar componentes dinámicamente. Puedes hacerlo usando el
servicio $injector :
Nota: si bien este método se puede usar para prevenir el problema de dependencia circular que
podría interrumpir su aplicación, no se considera una buena práctica evitar el problema al usarlo.
La dependencia circular generalmente indica que hay una falla en la arquitectura de su aplicación,
y usted debe abordar eso en su lugar.
De manera equivalente, podemos usar la anotación de propiedad $inject para lograr lo mismo
que arriba:
Puede cargar los servicios de AngularJS en JavaScript de vainilla utilizando el método del
injector() AngularJS. Cada elemento jqLite recuperado llamando angular.element() tiene un
método injector() que se puede usar para recuperar el inyector.
var service;
var serviceName = 'myService';
https://riptutorial.com/es/home 150
service = injector.get(serviceNameToInject);
}
https://riptutorial.com/es/home 151
Capítulo 31: Migración a Angular 2+
Introducción
AngularJS ha sido completamente reescrito usando el lenguaje TypeScript y renombrado a
simplemente Angular.
Se puede hacer mucho en una aplicación AngularJS para facilitar el proceso de migración. Como
dice la guía de actualización oficial , se pueden realizar varios "pasos de preparación" para
refactorizar su aplicación, haciéndola mejor y más cercana al nuevo estilo Angular.
Examples
Convertir su aplicación AngularJS en una estructura orientada a
componentes
En el nuevo marco angular, los componentes son los bloques de construcción principales que
componen la interfaz de usuario. Por lo tanto, uno de los primeros pasos que ayuda a migrar una
aplicación AngularJS al nuevo Angular es refactorizarlo en una estructura más orientada a los
componentes.
Preferiría mencionar algunos consejos sobre cómo convertir el antiguo código orientado a ng-
controller al nuevo estilo orientado a component .
HTML actual:
https://riptutorial.com/es/home 152
<div ng-controller="UserListController as listctrl">
<ul>
<li ng-repeat="user in myUserList">
{{ user }}
</li>
</ul>
</div>
JavaScript actual:
this.someFunction = function() {
// ...
}
// ...
}
nuevo HTML:
<user-list></user-list>
nuevo JavaScript:
app.component("UserList", {
templateUrl: 'user-list.html',
controller: UserListController
});
function UserListController(SomeService) {
this.someFunction = function() {
// ...
}
// ...
}
Observe cómo ya no estamos inyectando $scope en la función del controlador y ahora estamos
declarando this.myUserList lugar de $scope.myUserList ;
<ul>
<li ng-repeat="user in $ctrl.myUserList">
{{ user }}
</li>
</ul>
Observe cómo nos estamos refiriendo ahora a la variable myUserList , que pertenece al
https://riptutorial.com/es/home 153
controlador, usando $ctrl.myUserList de html en lugar de $scope.myUserList .
Esto se debe a que, como probablemente haya descubierto después de leer la documentación,
$ctrl en la plantilla ahora se refiere a la función del controlador.
$stateProvider
.state('users', {
url: '/users',
templateUrl: 'user-list.html',
controller: 'UserListController'
})
// ..
$stateProvider
.state('users', {
url: '/',
template: '<user-list></user-list>'
})
// ..
¿Que sigue?
Ahora que tiene un componente que contiene su aplicación (ya sea que contenga la aplicación
completa o una parte de ella, como una vista), ahora debe comenzar a dividir su componente en
múltiples componentes anidados, envolviendo partes de ella en nuevos subcomponentes , y así.
Después de leer la documentación del Componente , ya debe saber cómo usar todas las
funciones de esos componentes, pero si necesita un ejemplo concreto de una aplicación
realmente simple, puede verificar esto .
Además, si dentro del controlador de su componente tiene algunas funciones que contienen una
gran cantidad de código lógico, una buena idea puede ser considerar mover esa lógica a los
servicios .
https://riptutorial.com/es/home 154
Conclusión
La adopción de un enfoque basado en componentes empuja su AngularJS un paso más hacia la
migración al nuevo marco angular, pero también lo hace mejor y mucho más modular.
Por supuesto, hay muchos otros pasos que puede hacer para ir más allá en la nueva dirección
Angular 2+, que enumeraré en los siguientes ejemplos.
Cuando luego llevamos nuestras aplicaciones a producción, los cargadores de módulos también
hacen que sea más fácil empaquetarlos en paquetes de producción con baterías incluidas.
https://riptutorial.com/es/home 155
Capítulo 32: Módulos
Examples
Módulos
Creando un módulo:
angular
.module('app', []);
angular.module('app', [
'app.auth',
'app.dashboard'
]);
angular
.module('app');
Módulos
El módulo es un contenedor para varias partes de sus aplicaciones: controlador, servicios, filtros,
directivas, etc.
declarar un módulo
https://riptutorial.com/es/home 156
// if there are any required dependancies,
// then you can add in module, Like ['ngAnimate']
app.controller('myController', function() {
angular.module('myModule', []).
config(function(injectables) {
// here you can only inject providers in to config blocks.
});
2. Ejecutar bloques: se ejecuta después de que se crea el inyector y se utiliza para iniciar la
aplicación.
angular.module('myModule', []).
run(function(injectables) {
// here you can only inject instances in to config blocks.
});
https://riptutorial.com/es/home 157
Capítulo 33: MVC angular
Introducción
En AngularJS, el patrón MVC se implementa en JavaScript y HTML. La vista se define en HTML,
mientras que el modelo y el controlador se implementan en JavaScript. Hay varias maneras en
que estos componentes pueden unirse en AngularJS, pero la forma más simple comienza con la
vista.
Examples
La vista estática con controlador
mvc demo
Hola Mundo
https://riptutorial.com/es/home 158
Capítulo 34: ng-repetir
Introducción
La directiva ngRepeat una instancia de una plantilla una vez por elemento de una colección. La
colección debe ser una matriz o un objeto. Cada instancia de plantilla tiene su propio ámbito,
donde la variable de bucle dada se establece en el elemento de colección actual, y $index se
establece en el índice o clave del elemento.
Sintaxis
• <element ng-repeat="expression"></element>
• <div ng-repeat="(key, value) in myObj">...</div>
• <div ng-repeat="variable in expression">...</div>
Parámetros
Variable Detalles
$even boolean true si la posición del iterador $index es par (en caso contrario, false).
$odd boolean true si la posición del iterador $index es impar (en caso contrario, false).
Observaciones
AngularJS proporciona estos parámetros como variables especiales que están disponibles en la
expresión ng-repeat y en cualquier lugar dentro de la etiqueta HTML en la que vive ng-repeat.
Examples
Iterando sobre las propiedades del objeto.
Por ejemplo
https://riptutorial.com/es/home 159
<div ng-repeat="n in [42, 42, 43, 43]">
{{n}}
</div>
Seguimiento y duplicados
Duplicados
$scope.numbers = ['1','1','2','3','4'];
<ul>
<li ng-repeat="n in numbers track by $index">
{{n}}
</li>
</ul>
ng-repeat-start + ng-repeat-end
// table items
$scope.tableItems = [
{
row1: 'Item 1: Row 1',
row2: 'Item 1: Row 2'
},
{
row1: 'Item 2: Row 1',
row2: 'Item 2: Row 2'
}
];
// template
<table>
<th>
<td>Items</td>
</th>
<tr ng-repeat-start="item in tableItems">
<td ng-bind="item.row1"></td>
</tr>
<tr ng-repeat-end>
<td ng-bind="item.row2"></td>
</tr>
https://riptutorial.com/es/home 160
</table>
Salida:
Artículos
Artículo 1: Fila 1
Artículo 1: Fila 2
Artículo 2: Fila 1
Artículo 2: Fila 2
https://riptutorial.com/es/home 161
Capítulo 35: ng-view
Introducción
ng-view es una de las directivas integradas que Angular utiliza como contenedor para cambiar
entre vistas. {info} ngRoute ya no forma parte del archivo base angular.js, por lo que deberá incluir
el archivo angular-route.js después de su archivo de base angular javascript. Podemos configurar
una ruta utilizando la función "cuándo" del $ routeProvider. Primero debemos especificar la ruta,
luego, en un segundo parámetro, proporcionar un objeto con una propiedad templateUrl y una
propiedad de controlador.
Examples
ng-view
ng-view es una directiva que se usa con $route para representar una vista parcial en el diseño de
la página principal. Aquí, en este ejemplo, Index.html es nuestro archivo principal y cuando el
usuario llega a la ruta "/", templateURL home.html se representará en Index.html donde se
menciona ng-view .
angular.module('ngApp', ['ngRoute'])
.config(function($routeProvider){
$routeProvider.when("/",
{
templateUrl: "home.html",
controller: "homeCtrl"
}
);
});
angular.module('ngApp').controller('homeCtrl',['$scope', function($scope) {
$scope.welcome= "Welcome to stackoverflow!";
}]);
//Index.html
<body ng-app="ngApp">
<div ng-view></div>
</body>
Registro de navegación
var Registration=angular.module("myApp",["ngRoute"]);
https://riptutorial.com/es/home 162
2. ahora usamos $ routeProvider de "ngRoute"
Registration.config(function($routeProvider) {
});
Registration.config(function($routeProvider) {
$routeProvider
.when("/add", {
templateUrl : "regi.htm"
})
});
https://riptutorial.com/es/home 163
Capítulo 36: Opciones de enlaces AngularJS
(`=`, `@`, `&` etc.)
Observaciones
Usa este plunker para jugar con ejemplos.
Examples
@ enlace unidireccional, atributo de enlace.
El ámbito secundario obtiene su propio valor, si actualiza el valor, el ámbito principal tiene su
propio valor anterior (el ámbito secundario no puede modificar el valor del alcance de parens).
Cuando se cambia el valor del ámbito principal, también se cambiará el valor del ámbito primario.
Todas las interpolaciones aparecen cada vez en una llamada de resumen, no solo en la creación
de directivas.
= enlace bidireccional.
Al pasar un valor por referencia, desea compartir el valor entre ambos ámbitos y manipularlos
desde ambos ámbitos. No debe usar {{...}} para la interpolación.
https://riptutorial.com/es/home 164
</two-way>
Pasar la función por referencia es una mala idea: para permitir que el alcance cambie la definición
de una función, y se crearán dos observadores innecesarios, debe minimizar el conteo de
observadores.
Pasar un método en una directiva. Proporciona una forma de ejecutar una expresión en el
contexto del ámbito principal. El método se ejecutará en el ámbito del elemento primario, puede
pasar algunos parámetros desde el ámbito secundario allí. No debe usar {{...}} para la
interpolación. Cuando utiliza & en una directiva, genera una función que devuelve el valor de la
expresión evaluada en el ámbito principal (no es lo mismo que = donde acaba de pasar una
referencia).
angular.component("SampleComponent", {
bindings: {
title: '@',
movies: '<',
reservation: "=",
processReservation: "&"
}
});
@ indica que necesitamos un enlace muy básico , desde el ámbito principal al ámbito
secundario, sin ningún observador, de ninguna manera. Cada actualización en el ámbito primario
se mantendría en el ámbito primario, y cualquier actualización en el ámbito primario no se
comunicaría al ámbito primario.
https://riptutorial.com/es/home 165
= ya se conoce como un enlace de dos vías. Cada actualización en el ámbito primario se aplicaría
en los secundarios, y cada actualización secundaria se aplicaría al ámbito primario.
& ahora se utiliza para un enlace de salida. De acuerdo con la documentación del componente,
se debe utilizar para hacer referencia al método de alcance principal. En lugar de manipular el
alcance de los niños, ¡simplemente llame al método principal con los datos actualizados!
bindings: {
mandatory: '='
optional: '=?',
foo: '=?bar'
}
Los atributos opcionales deben marcarse con un signo de interrogación: =? o =?bar . Es protección
para ($compile:nonassign) excepción.
https://riptutorial.com/es/home 166
Capítulo 37: Perfil de rendimiento
Examples
Todo sobre perfilado
¿Qué es el perfil?
Por definición, la creación de perfiles es una forma de análisis dinámico de programas que mide,
por ejemplo, el espacio (memoria) o la complejidad del tiempo de un programa, el uso de
instrucciones particulares o la frecuencia y duración de las llamadas a funciones.
La creación de perfiles es importante porque no puede optimizar de manera efectiva hasta que
sepa en qué está gastando la mayor parte de su programa. Sin medir el tiempo de ejecución de
su programa (creación de perfiles), no sabrá si realmente lo ha mejorado.
Herramientas y Técnicas:
https://riptutorial.com/es/home 167
6. Use el siguiente código para averiguar manualmente el número de observadores en su
aplicación angular (crédito para @Words Like Jared Number of watchers )
(function() {
var root = angular.element(document.getElementsByTagName('body')),
watchers = [],
f = function(element) {
angular.forEach(['$scope', '$isolateScope'], function(scopeProperty) {
if(element.data() && element.data().hasOwnProperty(scopeProperty)) {
angular.forEach(element.data()[scopeProperty].$$watchers, function(watcher) {
watchers.push(watcher);
});
}
});
angular.forEach(element.children(), function(childElement) {
f(angular.element(childElement));
});
};
f(root);
7. Hay varias herramientas / sitios web disponibles en línea que facilitan una amplia gama de
funcionalidades para crear un perfil de su aplicación.
Con esto, puede ejecutar una prueba gratuita de velocidad de sitios web desde múltiples
ubicaciones en todo el mundo utilizando navegadores reales (IE y Chrome) y a velocidades
de conexión reales de los consumidores. Puede ejecutar pruebas simples o realizar pruebas
avanzadas que incluyen transacciones de varios pasos, captura de video, bloqueo de
contenido y mucho más.
Próximos pasos:
Hecho con perfilado. Sólo te lleva a mitad del camino. La siguiente tarea es convertir sus
descubrimientos en elementos de acción para optimizar su aplicación. Consulte esta
documentación sobre cómo puede mejorar el rendimiento de su aplicación angular con simples
trucos.
Feliz codificación :)
https://riptutorial.com/es/home 168
Capítulo 38: Perfilado y Rendimiento
Examples
7 mejoras simples de rendimiento
Trate de evitar las repeticiones anidadas tanto como sea posible. Una forma de mejorar el
rendimiento de ng-repeat es usar track by $index (o algún otro campo de identificación). Por
defecto, ng-repeat rastrea todo el objeto. Con track by , Angular mira el objeto solo por $index o id
de objeto.
Use otros enfoques como paginación , pergaminos virtuales , infinitos o limitTo: comience
siempre que sea posible para evitar iterar en grandes colecciones.
<div ng-bind="::my.data"></div>
https://riptutorial.com/es/home 169
<!-- Use single binding notation in ng-repeat where only list display is needed -->
<div ng-repeat="user in ::userCollection">
{{::user.data}}
</div>
El uso de la notación "unir una vez" le dice a Angular que espere a que el valor se estabilice
después de la primera serie de ciclos de digestión. Angular utilizará ese valor en el DOM, luego
eliminará a todos los observadores para que se convierta en un valor estático y ya no esté
vinculado al modelo.
Este ng-bind es una directiva y colocará un observador en la variable pasada. Por lo tanto, el ng-
bind solo se aplicará cuando el valor pasado realmente cambie.
Por otro lado, los corchetes se verán sucios y se actualizarán en cada $digest , incluso si no es
necesario.
Evita esto:
Mejor enfoque
app.controller('bigCalulations', function(valueService) {
// bad, because this is called in every digest loop
this.calculateMe = function() {
var t = 0;
for(i = 0; i < 1000; i++) {
t += i;
}
return t;
https://riptutorial.com/es/home 170
}
// good, because this is executed just once and logic is separated in service to keep
the controller light
this.preCalulatedValue = valueService.valueCalculation(); // returns 499500
});
4 observadores
Los observadores bajan tremendamente el rendimiento. Con más observadores, el bucle de
resumen tardará más tiempo y la interfaz de usuario se ralentizará. Si el observador detecta un
cambio, iniciará el bucle de resumen y volverá a representar la vista.
Hay tres formas de hacer una observación manual de cambios variables en Angular.
$watch(..., true) : evite esto tanto como sea posible, realizará una "observación profunda" y
disminuirá el rendimiento (observa más que watchCollection )
Tenga en cuenta que si está vinculando variables en la vista, está creando nuevos relojes: use
{{::variable}} para evitar la creación de un reloj, especialmente en bucles.
Como resultado, debe realizar un seguimiento de cuántos observadores está utilizando. Puede
contar a los observadores con este script (crédito para @Words Like Jared Number of watchers )
(function() {
var root = angular.element(document.getElementsByTagName('body')),
watchers = [],
f = function(element) {
angular.forEach(['$scope', '$isolateScope'], function(scopeProperty) {
if(element.data() && element.data().hasOwnProperty(scopeProperty)) {
angular.forEach(element.data()[scopeProperty].$$watchers, function(watcher) {
watchers.push(watcher);
});
}
});
angular.forEach(element.children(), function(childElement) {
f(angular.element(childElement));
});
};
f(root);
https://riptutorial.com/es/home 171
})();
5) ng-if / ng-show
Estas funciones son muy similares en comportamiento. ng-if elimina elementos del DOM,
mientras que ng-show solo oculta los elementos pero conserva todos los controladores. Si tiene
partes del código que no desea mostrar, use ng-if .
Depende del tipo de uso, pero a menudo uno es más adecuado que el otro.
6) Deshabilitar la depuración
De forma predeterminada, las directivas y los ámbitos de enlace dejan clases y marcas
adicionales en el código para ayudar con varias herramientas de depuración. Deshabilitar esta
opción significa que ya no procesa estos diversos elementos durante el ciclo de resumen.
Podría preguntarse sobre el costo de rendimiento asociado con el análisis de cadenas de todas
las funciones inyectables. Angular se encarga de esto almacenando en caché la propiedad $
inject después de la primera vez. Así que esto no ocurre cada vez que una función necesita ser
invocada.
CONSEJO PROFESIONAL: Si está buscando el enfoque con el mejor rendimiento, vaya con el
https://riptutorial.com/es/home 172
enfoque de anotación de propiedad de $ inyectar. Este enfoque evita por completo el análisis de
la definición de la función porque esta lógica se ajusta dentro de la siguiente comprobación en la
función de anotación: if (! ($ Inject = fn. $ Inject)). Si $ inyectar ya está disponible, ¡no se requiere
análisis!
app.controller('DemoController', DemoController);
PRO TIP 2: puede agregar una directiva ng-strict-di en el mismo elemento que ng-app para optar
al modo DI estricto, que generará un error cada vez que un servicio intente usar anotaciones
implícitas. Ejemplo:
angular.bootstrap(document, ['DemoApp'], {
strictDi: true
});
Esto conlleva el costo de ser un poco lento si se usa demasiado. Esto tendrá un mayor impacto
de rendimiento:
Agregue dos dos puntos :: antes del nombre de la variable para usar el enlace de una sola vez.
En este caso, el valor solo se actualiza una vez que se define my.data. Usted está apuntando
explícitamente a no observar los cambios en los datos. Angular no realizará ninguna verificación
de valores, lo que dará como resultado que se evalúen menos expresiones en cada ciclo de
resumen.
{{::my.data}}
https://riptutorial.com/es/home 173
<span ng-bind="::my.data"></span>
<span ng-if="::my.data"></span>
<span ng-repeat="item in ::my.data">{{item}}</span>
<span ng-class="::{ 'my-class': my.data }"></div>
Nota: Sin embargo, esto elimina el enlace de datos bidireccional para my.data , por lo que siempre
que este campo cambie en su aplicación, el mismo no se reflejará en la vista automáticamente.
Por lo tanto, úselo solo para valores que no cambiarán a lo largo de la vida útil de su
aplicación .
AngularJS tiene un bucle de resumen y todas sus funciones en una vista y filtros se ejecutan cada
vez que se ejecuta el ciclo de resumen. El bucle de resumen se ejecutará cada vez que se
actualice el modelo y puede ralentizar la aplicación (el filtro se puede golpear varias veces, antes
de que se cargue la página).
Mejor enfoque
.controller("bigCalulations", function(valueService) {
// bad, because this is called in every digest loop
this.calculateMe = function() {
var t = 0;
for(i = 0; i < 1000; i++) {
t = t + i;
}
return t;
}
//good, because it is executed just once and logic is separated in service to keep the
controller light
this.preCalulatedValue = valueService.caluclateSumm(); // returns 499500
});
Vigilantes
Los observadores necesitan ver algún valor y detectar que este valor ha cambiado.
https://riptutorial.com/es/home 174
observadores internos en el alcance actual.
Watcher es una función simple, que se llama en cada ciclo de resumen, y devuelve algo de valor.
Angular verifica el valor devuelto, si no es el mismo que en la llamada anterior: se ejecutará una
devolución de llamada que se pasó en el segundo parámetro para funcionar $watch() o
$watchCollection .
(function() {
angular.module("app", []).controller("ctrl", function($scope) {
$scope.value = 10;
$scope.$watch(
function() { return $scope.value; },
function() { console.log("value changed"); }
);
}
})();
Los observadores son asesinos de rendimiento. Cuantos más observadores tengas, más tiempo
tardarán en hacer un bucle de resumen, más lenta será la IU. Si un observador detecta cambios,
iniciará el ciclo de resumen (recálculo en todas las pantallas)
Hay tres formas de hacer una observación manual para cambios variables en Angular.
$watch(..., true) : evite esto tanto como sea posible, realizará una "observación profunda" y
eliminará el rendimiento (observa más que watchCollection)
Tenga en cuenta que si está vinculando variables en la vista, está creando nuevos observadores;
use {{::variable}} no para crear observadores, especialmente en bucles
Como resultado, debe realizar un seguimiento de cuántos observadores está utilizando. Puede
contar a los observadores con este script (crédito para @Words Like Jared - ¿Cómo contar el
número total de relojes en una página?
(function() {
var root = angular.element(document.getElementsByTagName("body")),
watchers = [];
var f = function(element) {
https://riptutorial.com/es/home 175
angular.forEach(element.children(), function(childElement) {
f(angular.element(childElement));
});
};
f(root);
console.log(watchersWithoutDuplicates.length);
})();
Si no desea crear su propio script, hay una utilidad de código abierto llamada ng-stats que utiliza
un gráfico en tiempo real integrado en la página para darle una idea del número de relojes que
Angular está administrando, así como el Frecuencia y duración de los ciclos de digestión a lo
largo del tiempo. La utilidad expone una función global llamada showAngularStats que puede llamar
para configurar cómo desea que funcione el gráfico.
showAngularStats({
"position": "topleft",
"digestTimeThreshold": 16,
"autoload": true,
"logDigest": true,
"logWatches": true
});
ng-if vs ng-show
Estas funciones son muy similares en comportamiento. La diferencia es que ng-if elimina
elementos del DOM. Si hay partes grandes del código que no se mostrarán, entonces ng-if es el
camino a seguir. ng-show solo ocultará los elementos pero conservará todos los manejadores.
ng-si
La directiva ngIf elimina o vuelve a crear una parte del árbol DOM en función de una expresión. Si
https://riptutorial.com/es/home 176
la expresión asignada a ngIf se evalúa como un valor falso, entonces el elemento se elimina del
DOM, de lo contrario, se reinserta en el DOM un clon del elemento.
ng-show
La directiva ngShow muestra u oculta el elemento HTML dado en función de la expresión
proporcionada al atributo ngShow. El elemento se muestra u oculta al eliminar o agregar la clase
de CSS ng-hide al elemento.
Ejemplo
<div ng-repeat="user in userCollection">
<p ng-if="user.hasTreeLegs">I am special
<!-- some complicated DOM -->
</p>
<p ng-show="user.hasSubscribed">I am aweosme
<!-- switch this setting on and off -->
</p>
</div>
Conclusión
Depende del tipo de uso, pero a menudo uno es más adecuado que el otro (por ejemplo, si el
95% del tiempo no se necesita el elemento, use ng-if ; si necesita cambiar la visibilidad del
elemento DOM, use ng-show ).
Nota : ng-if crea un nuevo alcance aislado, mientras que ng-show y ng-hide no lo hacen. Use
$parent.property si no se puede acceder directamente a la propiedad del ámbito principal.
Rebota tu modelo
<div ng-controller="ExampleController">
<form name="userForm">
Name:
<input type="text" name="userName"
ng-model="user.name"
ng-model-options="{ debounce: 1000 }" />
<button ng-click="userForm.userName.$rollbackViewValue();
user.name=''">Clear</button><br />
</form>
<pre>user.name = </pre>
</div>
https://riptutorial.com/es/home 177
ng-model con muchos ciclos de $digest .
Al usar rebotar en sus campos de entrada y en cualquier otro lugar donde no se requiera una
actualización instantánea, puede aumentar el rendimiento de sus aplicaciones Angular de manera
sustancial. No solo puede retrasar el tiempo, sino que también puede retrasarse cuando se
desencadena la acción. Si no desea actualizar su modelo ng con cada pulsación de tecla,
también puede actualizar el desenfoque.
Siempre debe anular el registro de otros ámbitos que no sean su alcance actual como se muestra
a continuación:
No tiene que anular el registro de las listas en el alcance actual, ya que angular se haría cargo de
ello:
No hacer
angular.module('app').controller('badExampleController', badExample);
badExample.$inject = ['$scope', '$rootScope'];
Hacer
angular.module('app').controller('goodExampleController', goodExample);
goodExample.$inject = ['$scope', '$rootScope'];
https://riptutorial.com/es/home 178
Capítulo 39: Prepararse para la producción -
Grunt
Examples
Ver precarga
Cuando se solicita la primera vista, normalmente Angular realiza una solicitud XHR para obtener
esa vista. Para proyectos de tamaño medio, el recuento de vistas puede ser significativo y puede
ralentizar la capacidad de respuesta de la aplicación.
La buena práctica es cargar previamente todas las vistas a la vez para proyectos pequeños y
medianos. Para proyectos más grandes, también es bueno agregarlos en algunos bultos
significativos, pero algunos otros métodos pueden ser útiles para dividir la carga. Para
automatizar esta tarea es útil utilizar tareas Grunt o Gulp.
Para precargar las vistas, podemos usar el objeto $templateCache . Ese es un objeto, donde
angular almacena cada vista recibida del servidor.
Es posible usar el módulo html2js , que convertirá todas nuestras vistas en un módulo: archivo js.
Entonces necesitaremos inyectar ese módulo en nuestra aplicación y eso es todo.
Para crear un archivo concatenado de todas las vistas podemos usar esta tarea.
grunt.initConfig({
pkg: require('./package.json'),
//section that sets up the settings for concatenation of the html files into one
file
html2js: {
options: {
base: '',
module: 'app.templates', //new module name
singleModule: true,
useStrict: true,
htmlmin: {
collapseBooleanAttributes: true,
collapseWhitespace: true
}
},
main: {
src: viewLocation,
dest: 'build/app.templates.js'
}
},
//this section is watching for changes in view files, and if there was a change,
it will regenerate the production file. This task can be handy during development.
watch: {
https://riptutorial.com/es/home 179
views:{
files: viewLocation,
tasks: ['buildHTML']
},
}
});
//to watch for changes and if the file has been changed, regenerate the file
grunt.loadNpmTasks('grunt-contrib-watch');
Para usar esta forma de concatinación, necesita hacer 2 cambios: En su archivo index.html
necesita hacer referencia al archivo de vista concatenada
<script src="build/app.templates.js"></script>
angular.module('app', ['app.templates'])
.state('home', {
url: '/home',
views: {
"@": {
controller: 'homeController',
//this will be picked up from $templateCache
templateUrl: 'app/views/home.html'
},
}
})
Optimización de scripts
Es una buena práctica combinar los archivos JS y minimizarlos. Para proyectos más grandes,
podría haber cientos de archivos JS y agrega una latencia innecesaria para cargar cada archivo
por separado del servidor.
Para la minificación angular se requiere tener todas las funciones anotadas. Eso es necesario
para la inyección de dependencia angular adecuada minificación. (Durante la minificación, los
nombres de las funciones y las variables serán renombrados y se interrumpirá la inyección de
dependencia si no se toman acciones adicionales).
Durante minificaiton $scope y myService variables serán reemplazadas por algunos otros valores.
https://riptutorial.com/es/home 180
La inyección de dependencia angular funciona según el nombre, como resultado, estos nombres
no deben cambiar
module.exports = function (grunt) {// configura la ubicación de tus scripts aquí para reutilizarlos en
el código var scriptLocation = ['app / scripts / *. js'];
grunt.initConfig({
pkg: require('./package.json'),
//add necessary annotations for safe minification
ngAnnotate: {
angular: {
src: ['staging/concatenated.js'],
dest: 'staging/anotated.js'
}
},
//combines all the files into one file
concat: {
js: {
src: scriptLocation,
dest: 'staging/concatenated.js'
}
},
//final uglifying
uglify: {
options: {
report: 'min',
mangle: false,
sourceMap:true
},
my_target: {
files: {
'build/app.min.js': ['staging/anotated.js']
}
}
},
//this section is watching for changes in JS files, and if there was a change, it will
regenerate the production file. You can choose not to do it, but I like to keep concatenated
version up to date
watch: {
scripts: {
files: scriptLocation,
https://riptutorial.com/es/home 181
tasks: ['buildJS']
}
}
});
//to watch for changes and if the file has been changed, regenerate the file
grunt.loadNpmTasks('grunt-contrib-watch');
//task that sequentially executes all steps to prepare JS file for production
//concatinate all JS files
//annotate JS file (prepare for minification
//uglify file
grunt.registerTask('buildJS', ['concat:js', 'ngAnnotate', 'uglify']);
};
https://riptutorial.com/es/home 182
Capítulo 40: Promesas angulares con
servicio $ q
Examples
Usando $ q.all para manejar múltiples promesas
Puede usar la función $q.all para llamar a un método .then después de que una serie de
promesas se haya resuelto con éxito y recuperar los datos con los que se resolvieron.
Ejemplo:
JS:
$scope.data = []
$q.all([
$http.get("data.json"),
$http.get("more-data.json"),
]).then(function(responses) {
$scope.data = responses.map((resp) => resp.data);
});
El código anterior se ejecuta $http.get 2 veces para los datos en archivos JSON locales, cuando
ambos get método completo que resuelven sus promesas asociadas, cuando se resuelvan todas
las promesas de la matriz, la .then método comienza con las dos promesas de datos dentro de
las responses argumento de la matriz.
Luego, los datos se asignan para que se puedan mostrar en la plantilla, luego podemos mostrar
HTML:
<ul>
<li ng-repeat="d in data">
<ul>
<li ng-repeat="item in d">{{item.name}}: {{item.occupation}}</li>
</ul>
</li>
</ul>
JSON:
[{
"name": "alice",
"occupation": "manager"
}, {
"name": "bob",
"occupation": "developer"
}]
https://riptutorial.com/es/home 183
Usando el constructor $ q para crear promesas
La función constructora $q se utiliza para crear promesas a partir de API asíncronas que utilizan
devoluciones de llamada para devolver resultados.
La función constructora recibe una función que se invoca con dos argumentos, resolve y reject
que son funciones que se utilizan para resolver o rechazar la promesa.
Ejemplo 1:
Ejemplo 2:
$scope.divide = function(a, b) {
return $q(function(resolve, reject) {
if (b===0) {
return reject("Cannot devide by 0")
} else {
return resolve(a/b);
}
});
}
El código anterior que muestra una función de división promisificada, devolverá una promesa con
el resultado o rechazará con una razón si el cálculo es imposible.
$scope.divide(7, 2).then(function(result) {
// will return 3.5
}, function(err) {
// will not run
})
https://riptutorial.com/es/home 184
$scope.divide(2, 0).then(function(result) {
// will not run as the calculation will fail on a divide by 0
}, function(err) {
// will return the error string.
})
Podemos usar $q para aplazar las operaciones hacia el futuro mientras tenemos un objeto de
promesa pendiente en el presente, mediante el uso de $q.defer Nosotros creamos una promesa
que se resolverá o rechazará en el futuro.
Este método no es equivalente al uso del constructor $q , ya que usamos $q.defer a prometer una
rutina existente que puede o no devolver (o alguna vez ha devuelto) una promesa.
Ejemplo:
// and then
runAnimation.then(function(status) {}, function(error) {})
2. Asegúrese de que siempre resuelve o rechaza su objeto diferido o, de lo .then posible que
no se ejecute y corre el riesgo de una pérdida de memoria.
$q es un servicio incorporado que ayuda a ejecutar funciones asíncronas y a usar sus valores de
retorno (o excepción) cuando finalizan el procesamiento.
$q se integra con el mecanismo de observación del modelo $rootScope.Scope , lo que significa una
propagación más rápida de la resolución o el rechazo en sus modelos y evita repinturas
innecesarias en el navegador, lo que daría como resultado una interfaz de usuario parpadeante.
En nuestro ejemplo, llamamos a nuestra fábrica getMyData , que devuelve un objeto de promesa.
Si el objeto se resolved , devuelve un número aleatorio. Si se rejected , devuelve un rechazo con
un mensaje de error después de 2 segundos.
https://riptutorial.com/es/home 185
En fabrica angular
angular.module('app', [])
.factory('getMyData', getMyData)
.run(function(getData) {
var promise = getData()
.then(function(string) {
console.log(string)
}, function(error) {
console.error(error)
})
.finally(function() {
console.log('Finished at:', new Date())
})
})
Para usar promesas, inyecte $q como dependencia. Aquí inyectamos $q en la fábrica getMyData .
Un objeto diferido es simplemente un objeto que expone una promesa, así como los métodos
asociados para resolverla. Se construye utilizando la función $q.deferred() y expone tres métodos
principales: resolve() , reject() y notify() .
Propiedades
Se accede al objeto de promesa asociado a través de la propiedad de promesa. promise -
{Promesa} - promete el objeto asociado con este aplazado.
https://riptutorial.com/es/home 186
Se crea una nueva instancia de promesa cuando se crea una instancia diferida y se puede
recuperar llamando a deferred.promise .
El propósito del objeto de promise es permitir que las partes interesadas tengan acceso al
resultado de la tarea diferida cuando se complete.
Métodos de promesa
Ejemplo 1:
return promise;
}
https://riptutorial.com/es/home 187
.then(function (num) {
// 1
console.log(num);
return --num;
})
.then(function (num) {
// 0
console.log(num);
return 'And we are done!';
})
.then(function (text) {
// "And we are done!"
console.log(text);
});
Si todo lo que necesita es envolver el valor en una promesa, no necesita usar la sintaxis larga
como aquí:
//OVERLY VERBOSE
var defer;
defer = $q.defer();
defer.resolve(['one', 'two']);
return defer.promise;
//BETTER
return $q.when(['one', 'two']);
https://riptutorial.com/es/home 188
Evita este Anti-Patrón
$http(config).then(function(res) {
myDeferred.resolve(res);
}, function(error) {
myDeferred.reject(error);
});
return myDeferred.promise;
No hay necesidad de fabricar una promesa con $q.defer ya que el servicio $ http ya devuelve una
promesa.
//INSTEAD
return $http(config);
https://riptutorial.com/es/home 189
Capítulo 41: Proveedores
Sintaxis
• constante (nombre, valor);
• valor (nombre, valor);
• fábrica (nombre, $ getFn);
• servicio (nombre, constructor);
• proveedor (nombre, proveedor);
Observaciones
Los proveedores son objetos singleton que se pueden inyectar, por ejemplo, en otros servicios,
controladores y directivas. Todos los proveedores están registrados con diferentes "recetas",
donde el Provider es el más flexible. Todas las recetas posibles son:
• Constante
• Valor
• Fábrica
• Servicio
• Proveedor
Los servicios, las fábricas y los proveedores están todos iniciados, el componente se inicializa
solo si la aplicación depende de él.
Los decoradores están estrechamente relacionados con los proveedores. Los decoradores se
utilizan para interceptar el servicio o la creación de fábrica para cambiar su comportamiento o
anularlo (partes de).
Examples
Constante
angular.module('app',[])
.constant('endpoint', 'http://some.rest.endpoint') // define
.config(function(endpoint) {
// do something with endpoint
// available in both config- and run phases
})
.controller('MainCtrl', function(endpoint) { // inject
var vm = this;
vm.endpoint = endpoint; // usage
});
https://riptutorial.com/es/home 190
<body ng-controller="MainCtrl as vm">
<div>endpoint = {{ ::vm.endpoint }}</div>
</body>
Valor
angular.module('app',[])
.value('endpoint', 'http://some.rest.endpoint') // define
.run(function(endpoint) {
// do something with endpoint
// only available in run phase
})
.controller('MainCtrl', function(endpoint) { // inject
var vm = this;
vm.endpoint = endpoint; // usage
});
Fábrica
La receta de Factory construye un nuevo servicio utilizando una función con cero o
más argumentos (son dependencias de otros servicios). El valor de retorno de esta
función es la instancia de servicio creada por esta receta.
Factory puede crear un servicio de cualquier tipo, ya sea primitivo, objeto literal,
función o incluso una instancia de un tipo personalizado.
angular.module('app',[])
.factory('endpointFactory', function() {
return {
get: function() {
return 'http://some.rest.endpoint';
}
};
})
.controller('MainCtrl', function(endpointFactory) {
var vm = this;
vm.endpoint = endpointFactory.get();
});
https://riptutorial.com/es/home 191
<body ng-controller="MainCtrl as vm">
<div>endpoint = {{::vm.endpoint }}</div>
</body>
Servicio
La receta de Servicio produce un servicio como las recetas de Valor o Fábrica, pero lo
hace invocando a un constructor con el nuevo operador . El constructor puede tomar
cero o más argumentos, que representan dependencias necesarias para la instancia
de este tipo.
angular.module('app',[])
.service('endpointService', function() {
this.get = function() {
return 'http://some.rest.endpoint';
};
})
.controller('MainCtrl', function(endpointService) {
var vm = this;
vm.endpoint = endpointService.get();
});
Proveedor
Debe usar la receta del proveedor solo cuando desee exponer una API para la
configuración de toda la aplicación que debe realizarse antes de que se inicie la
aplicación. Por lo general, esto es interesante solo para los servicios reutilizables cuyo
comportamiento puede necesitar variar ligeramente entre las aplicaciones.
angular.module('app',[])
.provider('endpointProvider', function() {
var uri = 'n/a';
this.set = function(value) {
https://riptutorial.com/es/home 192
uri = value;
};
this.$get = function() {
return {
get: function() {
return uri;
}
};
};
})
.config(function(endpointProviderProvider) {
endpointProviderProvider.set('http://some.rest.endpoint');
})
.controller('MainCtrl', function(endpointProvider) {
var vm = this;
vm.endpoint = endpointProvider.get();
});
punto final = n / a
https://riptutorial.com/es/home 193
Capítulo 42: Proyecto Angular - Estructura de
Directorio
Examples
Estructura de directorios
Una pregunta común entre los nuevos programadores angulares: "¿Cuál debería ser la estructura
del proyecto?". Una buena estructura ayuda a un desarrollo de aplicaciones escalable. Cuando
comenzamos un proyecto, tenemos dos opciones, Ordenar por tipo (izquierda) y Ordenar por
característica (derecha). El segundo es mejor, especialmente en aplicaciones grandes, el
proyecto se vuelve mucho más fácil de administrar.
https://riptutorial.com/es/home 194
La aplicación está organizada por el tipo de archivos.
• Ventaja : buena para aplicaciones pequeñas, para los programadores que solo comienzan a
usar Angular y es fácil de convertir al segundo método.
• Desventaja : incluso para las aplicaciones pequeñas comienza a ser más difícil encontrar
un archivo específico. Por ejemplo, una vista y su controlador están en dos carpetas
separadas.
Todas las vistas de diseño y los controladores van en la carpeta de diseño, el contenido del
administrador va en la carpeta de administración, etc.
• Ventaja : cuando se busca una sección del código que determina una determinada
característica, todo está ubicado en una carpeta.
• Desventaja : los servicios son un poco diferentes ya que “atienden” muchas características.
Puedes leer más sobre esto en Estructura angular: Refactorización para el crecimiento
https://riptutorial.com/es/home 195
Crédito a: Guía de estilo angular
https://riptutorial.com/es/home 196
Capítulo 43: Pruebas unitarias
Observaciones
Este tema proporciona ejemplos para la prueba unitaria de las diversas construcciones en
AngularJS. Las pruebas unitarias a menudo se escriben utilizando Jasmine , un popular marco de
pruebas basado en el comportamiento. Cuando la unidad realice pruebas angulares, deberá
incluir ngMock como una dependencia al ejecutar las pruebas de la unidad.
Examples
Unidad de prueba de un filtro.
La prueba:
describe('multiplierFilter', function() {
var filter;
beforeEach(function() {
module('myModule');
inject(function(multiplierFilter) {
filter = multiplierFilter;
});
});
https://riptutorial.com/es/home 197
});
});
¡Correr!
angular.module('myModule', []).component('myComponent', {
bindings: {
myValue: '<'
},
controller: function(MyService) {
this.service = MyService;
this.componentMethod = function() {
return 2;
};
}
});
La prueba:
describe('myComponent', function() {
var component;
beforeEach(function() {
module('myModule');
inject(function($componentController) {
// 1st - component name, 2nd - controller injections, 3rd - bindings
component = $componentController('myComponent', {
MyService: MyServiceFake
}, {
myValue: 3
});
});
});
¡Correr!
https://riptutorial.com/es/home 198
Unidad de prueba de un controlador.
angular.module('myModule', [])
.controller('myController', function($scope) {
$scope.num = 2;
$scope.doSomething = function() {
$scope.num += 2;
}
});
La prueba:
describe('myController', function() {
var $scope;
beforeEach(function() {
module('myModule');
inject(function($controller, $rootScope) {
$scope = $rootScope.$new();
$controller('myController', {
'$scope': $scope
})
});
});
it('should increment `num` by 2', function() {
expect($scope.num).toEqual(2);
$scope.doSomething();
expect($scope.num).toEqual(4);
});
});
¡Correr!
Código de servicio
angular.module('myModule', [])
.service('myService', function() {
this.doSomething = function(someNumber) {
return someNumber + 2;
}
});
La prueba
describe('myService', function() {
var myService;
beforeEach(function() {
module('myModule');
inject(function(_myService_) {
myService = _myService_;
});
});
https://riptutorial.com/es/home 199
it('should increment `num` by 2', function() {
var result = myService.doSomething(4);
expect(result).toEqual(6);
});
});
¡Correr!
Código directivo
angular.module('myModule', [])
.directive('myDirective', function() {
return {
template: '<div>{{greeting}} {{name}}!</div>',
scope: {
name: '=',
greeting: '@'
}
};
});
La prueba
describe('myDirective', function() {
var element, scope;
beforeEach(function() {
module('myModule');
inject(function($compile, $rootScope) {
scope = $rootScope.$new();
element = angular.element("<my-directive name='name' greeting='Hello'></my-directive>");
$compile(element)(scope);
/* PLEASE NEVER USE scope.$digest(). scope.$apply use a protection to avoid to run a
digest loop when there is already one, so, use scope.$apply() instead. */
scope.$apply();
})
});
¡Correr!
https://riptutorial.com/es/home 200
Lea Pruebas unitarias en línea: https://riptutorial.com/es/angularjs/topic/1689/pruebas-unitarias
https://riptutorial.com/es/home 201
Capítulo 44: recorrido del bucle de digestión
Sintaxis
• $ scope. $ watch (watchExpression, callback, [deep compare])
• $ scope. $ digest ()
• $ scope. $ apply ([exp])
Examples
enlace de datos de dos vías
Angular tiene algo de magia bajo su capucha. permite vincular DOM a variables js reales.
Angular utiliza un bucle, denominado " bucle de resumen ", que se llama después de cualquier
cambio de una variable: llamadas devoluciones de llamada que actualizan el DOM.
En algún momento, el bucle de resumen itera sobre una devolución de llamada que actualiza el
contenido de este intervalo:
<span>{{variable}}</span>
El ciclo de vida básico de este ejemplo, resume (muy esquemáticamente) cómo funciona el
ángulo:
$ digerir y $ ver
La implementación del enlace de datos de dos vías, para lograr el resultado del ejemplo anterior,
se podría realizar con dos funciones principales:
• $ digest se llama después de una interacción del usuario (vinculación DOM => variable)
https://riptutorial.com/es/home 202
• $ watch establece una devolución de llamada para que se llame después de los cambios de
la variable (variable de enlace => DOM)
<input id="input"/>
<span id="span"></span>
Ahora podríamos usar estas funciones para conectar una variable al DOM (angular viene con
directivas integradas que lo harán por usted):
var realVar;
//this is usually done by ng-model directive
input1.addEventListener('keyup',function(e){
realVar=e.target.value;
$digest()
}, true);
Por supuesto, las implementaciones reales son más complejas y admiten parámetros como el
elemento a enlazar y la variable a usar.
el arbol $ scope
https://riptutorial.com/es/home 203
Esta ng-repeat une 5 elementos a 5 variables llamadas number , ¡con un valor diferente para cada
una de ellas!
La forma en que angular logra este comportamiento es mediante el uso de un contexto separado
para cada elemento que necesita variables separadas. Este contexto se llama un alcance.
Cada ámbito contiene propiedades, que son las variables vinculadas al DOM, y las funciones
$digest y $watch se implementan como métodos del alcance.
El DOM es un árbol, y las variables deben usarse en diferentes niveles del árbol:
<div>
<input ng-model="person.name" />
<span ng-repeat="number in [1,2,3,4,5]">{{number}} {{person.name}}</span>
</div>
Pero como vimos, el contexto (o alcance) de las variables dentro de ng-repeat es diferente al
contexto que se encuentra arriba. Para resolver esto - angular implementa ámbitos como un
árbol.
Cada alcance tiene una variedad de hijos, y llamar a su método $digest ejecutará todo su método
$digest niños.
De esta manera, después de cambiar la entrada, se llama $digest para el alcance del div, que
luego ejecuta $digest para sus 5 hijos, que actualizará su contenido.
function $scope(){
this.$children = [];
this.$watches = [];
}
$scope.prototype.$digest = function(){
this.$watches.forEach(function($w){
var val = $w.val();
if($w.prevVal !== val){
$w.callback(val, $w.prevVal);
$w.prevVal = val;
}
});
this.$children.forEach(function(c){
c.$digest();
});
}
https://riptutorial.com/es/home 204
Lea recorrido del bucle de digestión en línea:
https://riptutorial.com/es/angularjs/topic/3156/recorrido-del-bucle-de-digestion
https://riptutorial.com/es/home 205
Capítulo 45: Servicio Distinguido vs Fábrica
Examples
Factory VS Service una vez por todas
Por definición:
Los servicios son básicamente funciones de constructor. Utilizan la palabra clave 'this'.
Bajo el capó:
Debate:
Las fábricas pueden ejecutar código antes de que devolvamos nuestro objeto literal.
Pero al mismo tiempo, los Servicios también se pueden escribir para devolver un objeto literal y
para ejecutar código antes de regresar. Aunque eso es contraproducente ya que los servicios
están diseñados para actuar como una función constructora.
La sintaxis de servicios del constructor es más cercana a la sintaxis de clase de ES6. Así que la
migración será fácil.
Resumen
Una fábrica es un caso especial de un proveedor cuando todo lo que necesita en su proveedor es
una función $ get (). Te permite escribirlo con menos código.
Un servicio es un caso especial de una fábrica cuando desea devolver una instancia de un nuevo
objeto, con el mismo beneficio de escribir menos código.
https://riptutorial.com/es/home 206
Lea Servicio Distinguido vs Fábrica en línea:
https://riptutorial.com/es/angularjs/topic/7099/servicio-distinguido-vs-fabrica
https://riptutorial.com/es/home 207
Capítulo 46: Servicios
Examples
Cómo crear un servicio
angular.module("app")
.service("counterService", function(){
var service = {
number: 0
};
return service;
});
angular.module("app")
// editable
<input ng-model="counter.number" />
// read-only
<span ng-bind="counter.number"></span>
Por supuesto, en código real, interactuarías con el servicio utilizando métodos en el controlador,
que a su vez delegan en el servicio. El ejemplo anterior simplemente incrementa el valor del
contador cada vez que se usa el controlador en una plantilla.
Los servicios son objetos singleton que se instancian solo una vez por aplicación (por el $
inyector) y se cargan perezosamente (creados solo cuando es necesario).
Un singleton es una clase que solo permite crear una instancia de sí mismo, y brinda
https://riptutorial.com/es/home 208
un acceso simple y fácil a dicha instancia. Como se indica aquí
.factory('dataService', function() {
var dataObject = {};
var service = {
// define the getter method
get data() {
return dataObject;
},
// define the setter method
set data(value) {
dataObject = value || {};
}
};
// return the "service" object to expose the getter/setter
return service;
})
.controller('controllerOne', function(dataService) {
// create a local reference to the dataService
this.dataService = dataService;
// create an object to store
var someObject = {
name: 'SomeObject',
value: 1
};
// store the object
this.dataService.data = someObject;
})
.controller('controllerTwo', function(dataService) {
// create a local reference to the dataService
this.dataService = dataService;
// this will automatically update with any changes to the shared data object
this.objectFromControllerOne = this.dataService.data;
})
inyectar fuentes externas y HTML en bruto en la plantilla requiere el ajuste manual de $sce .
Manifestación
https://riptutorial.com/es/home 209
return function(content) {
return $sce.trustAsResourceUrl(content);
};
}]);
Uso en plantilla
</div>
angular.module("app")
.service("counterService", ["fooService", "barService", function(anotherService,
barService){
var service = {
number: 0,
foo: function () {
return fooService.bazMethod(); // Use of 'fooService'
},
bar: function () {
return barService.bazMethod(); // Use of 'barService'
}
};
return service;
}]);
Registro de un servicio
La forma más común y flexible de crear un servicio utiliza la fábrica de API angular.module:
La función de fábrica de servicios puede ser una función o una matriz, al igual que la forma en
que creamos los controladores:
https://riptutorial.com/es/home 210
Para exponer un método en nuestro servicio, podemos colocarlo como un atributo en el objeto de
servicio.
angular.module('myApp.services', [])
.factory('githubService', function($http) {
var githubUrl = 'https://api.github.com';
var runUserRequest = function(username, path) {
// Return the promise from the $http service
// that calls the Github API using JSONP
return $http({
method: 'JSONP',
url: githubUrl + '/users/' +
username + '/' +
path + '?callback=JSON_CALLBACK'
});
}
// Return the service object with a single function
// events
return {
events: function(username) {
return runUserRequest(username, 'events');
}
};
1) Servicios
Un servicio es una función de constructor que se invoca una vez en tiempo de ejecución con el
new , al igual que lo que haríamos con el Javascript simple con la única diferencia de que AngularJs
está llamando al new detrás de escena.
Veamos un ejemplo sencillo en el que registraríamos un servicio que usa el servicio $http para
obtener los detalles de los estudiantes y usarlos en el controlador
function StudentDetailsService($http) {
this.getStudentDetails = function getStudentDetails() {
return $http.get('/details');
};
}
angular.module('myapp').service('StudentDetailsService', StudentDetailsService);
function StudentController(StudentDetailsService) {
StudentDetailsService.getStudentDetails().then(function (response) {
// handle response
});
}
https://riptutorial.com/es/home 211
angular.module('app').controller('StudentController', StudentController);
¿Cuándo usar?
Use .service() donde quiera que quiera usar un constructor. Normalmente se usa para crear API
públicas como getStudentDetails() . Pero si no desea usar un constructor y desea usar un patrón
de API simple, entonces no hay mucha flexibilidad en .service() .
2) Fábrica
A pesar de que podemos lograr todas las cosas usando .factory() que haríamos, usando
.services() , no hace que .factory() "igual que" .service() . Es mucho más potente y flexible que
.service()
Veamos un ejemplo donde se usa la fábrica para devolver un objeto usando un patrón de módulo
Revelación básico
function StudentDetailsService($http) {
function getStudentDetails() {
return $http.get('/details');
}
return {
getStudentDetails: getStudentDetails
};
}
angular.module('myapp').factory('StudentDetailsService', StudentDetailsService);
function StudentController(StudentDetailsService) {
StudentDetailsService.getStudentDetails().then(function (response) {
// handle response
});
}
angular.module('app').controller('StudentController', StudentController);
Cierres de retorno
¿Qué es un cierre?
Los cierres son funciones que se refieren a variables que se usan localmente, PERO definidas en
https://riptutorial.com/es/home 212
un ámbito de cierre.
function closureFunction(name) {
function innerClosureFunction(age) { // innerClosureFunction() is the inner function, a
closure
// Here you can manipulate 'age' AND 'name' variables both
};
};
La parte "maravillosa" es que puede acceder al name que está en el ámbito principal.
function StudentDetailsService($http) {
function closureFunction(name) {
function innerClosureFunction(age) {
// Here you can manipulate 'age' AND 'name' variables
};
};
};
angular.module('myapp').factory('StudentDetailsService', StudentDetailsService);
function StudentController(StudentDetailsService) {
var myClosure = StudentDetailsService('Student Name'); // This now HAS the
innerClosureFunction()
var callMyClosure = myClosure(24); // This calls the innerClosureFunction()
};
angular.module('app').controller('StudentController', StudentController);
.service()crea constructores con una llamada a new como se ve arriba. .factory() también puede
crear constructores con una llamada a new
function StudentDetailsService($http) {
function Student() {
this.age = function () {
return 'This is my age';
};
}
Student.prototype.address = function () {
return 'This is my address';
};
return Student;
};
angular.module('myapp').factory('StudentDetailsService', StudentDetailsService);
https://riptutorial.com/es/home 213
Uso dentro de un controlador
function StudentController(StudentDetailsService) {
var newStudent = new StudentDetailsService();
//Now the instance has been created. Its properties can be accessed.
newStudent.age();
newStudent.address();
};
angular.module('app').controller('StudentController', StudentController);
https://riptutorial.com/es/home 214
Capítulo 47: SignalR con AngularJs
Introducción
En este artículo, nos centramos en "Cómo crear un proyecto simple utilizando AngularJs y
SignalR", en esta capacitación que necesita saber sobre "cómo crear una aplicación con
angularjs", "cómo crear / utilizar el servicio en angular" y conocimientos básicos sobre SignalR
"para esto recomendamos https://www.codeproject.com/Tips/590660/Introduction-to-SignalR) .
Examples
SignalR y AngularJs [ChatProject]
- Application
- app.js
- Controllers
- appController.js
- Factories
- SignalR-factory.js
- index.html
- Scripts
- angular.js
- jquery.js
- jquery.signalR.min.js
- Hubs
Startup.cs
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(SignalR.Hubs.Startup))]
namespace SignalR.Hubs
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
}
https://riptutorial.com/es/home 215
ChatHub.cs
using Microsoft.AspNet.SignalR;
namespace SignalR.Hubs
{
public class ChatHub : Hub
{
public void Send(string name, string message, string time)
{
Clients.All.broadcastMessage(name, message, time);
}
}
}
app.js
SignalR-factory.js
app.factory("signalR", function () {
var factory = {};
factory.connectToHub = function () {
return $.connection[factory.hub];
}
factory.client = function () {
var hub = factory.connectToHub();
return hub.client;
}
factory.server = function () {
var hub = factory.connectToHub();
return hub.server;
}
https://riptutorial.com/es/home 216
return factory;
});
app.run(function(signalR) {
signalR.url("http://localhost:21991/signalr");
});
signalR.setHubName("chatHub");
$scope.$apply(function() {
$scope.messages.push(newChat);
});
};
signalR.start(function () {
$scope.send = function () {
var dt = new Date();
var time = dt.getHours() + ":" + dt.getMinutes() + ":" + dt.getSeconds();
signalR.client () | este método intenta conectarse a sus hubs y obtener todas las
funciones en los Hubs, en este ejemplo tenemos "chatHub", para obtener la función
"broadcastMessage ()";
index.html
<!DOCTYPE html>
https://riptutorial.com/es/home 217
<html ng-app="app" ng-controller="ctrl">
<head>
<meta charset="utf-8" />
<title>SignalR Simple Chat</title>
</head>
<body>
<form>
<input type="text" placeholder="name" ng-model="user.name" />
<input type="text" placeholder="message" ng-model="user.message" />
<button ng-click="send()">send</button>
<ul>
<li ng-repeat="item in messages">
<b ng-bind="item.name"></b> <small ng-bind="item.time"></small> :
{{item.message}}
</li>
</ul>
</form>
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/jquery-1.6.4.min.js"></script>
<script src="Scripts/jquery.signalR-2.2.1.min.js"></script>
<script src="signalr/hubs"></script>
<script src="app.js"></script>
<script src="SignalR-factory.js"></script>
</body>
</html
https://riptutorial.com/es/home 218
Capítulo 48: solicitud de $ http
Examples
Usando $ http dentro de un controlador
El servicio $http es una función que genera una solicitud HTTP y devuelve una promesa.
Uso general
appName.controller('controllerName',
['$http', function($http){
$http servicio $http también tiene métodos de acceso directo. Lea acerca de los métodos http
aquí
Sintaxis
https://riptutorial.com/es/home 219
• $ http.get
• $ http.head
• $ http.post
• $ http.put
• $ http.delete
• $ http.jsonp
• $ http.patch
Las solicitudes HTTP se usan ampliamente en repetidas ocasiones en todas las aplicaciones
web, por lo que es aconsejable escribir un método para cada solicitud común y luego usarlo en
varios lugares a lo largo de la aplicación.
Crear un httpRequestsService.js
httpRequestsService.js
return {
// function that performs a basic get request
getName: function(){
// make sure $http is injected
return $http.get("/someAPI/names")
.then(function(response) {
// return the result as a promise
return response;
}, function(response) {
// defer the promise
return $q.reject(response.data);
});
},
El servicio anterior realizará una solicitud de obtención dentro del servicio. Esto estará disponible
para cualquier controlador donde se haya inyectado el servicio.
Uso de la muestra
appName.controller('controllerName',
['httpRequestsService', function(httpRequestsService){
https://riptutorial.com/es/home 220
}, function(error){
// do something with the error
})
}])
Las solicitudes de $ http requieren un tiempo que varía según el servidor, algunas pueden tardar
unos milisegundos y otras pueden tardar unos segundos. A menudo, el tiempo requerido para
recuperar los datos de una solicitud es crítico. Suponiendo que el valor de la respuesta es una
matriz de nombres, considere el siguiente ejemplo:
Incorrecto
$scope.names = [];
$http({
method: 'GET',
url: '/someURL'
}).then(function successCallback(response) {
$scope.names = response.data;
},
function errorCallback(response) {
alert(response.status);
});
El acceso a $scope.names[0] justo debajo de la solicitud $ http a menudo generará un error: esta
línea de código se ejecuta antes de que se reciba la respuesta del servidor.
Correcto
$scope.names = [];
$http({
method: 'GET',
url: '/someURL'
}).then(function successCallback(response) {
$scope.names = response.data;
},
function errorCallback(response) {
alert(response.status);
});
https://riptutorial.com/es/home 221
Usando el servicio $ watch , accedemos a la matriz $scope.names solo cuando se recibe la
respuesta. Durante la inicialización, la función se llama aunque $scope.names se haya inicializado
antes, por lo tanto, verificar si newVal.length es diferente de 0 es necesario. Tenga en cuenta que
cualquier cambio realizado en $scope.names activará la función de observación.
https://riptutorial.com/es/home 222
Capítulo 49: Tareas roncas
Examples
Ejecutar la aplicación localmente
El siguiente ejemplo requiere que node.js esté instalado y npm esté disponible.
El código completo de trabajo se puede obtener de GitHub @
https://github.com/mikkoviitala/angular-grunt-run-local
Por lo general, una de las primeras cosas que desea hacer al desarrollar una nueva aplicación
web es hacer que se ejecute localmente.
A continuación encontrará un ejemplo completo de cómo lograrlo, usando grunt (javascript task
runner), npm (administrador de paquetes de nodo) y bower (otro administrador de paquete).
paquete.json
Vamos a estar instalando ronco sí, matchdep para hacer nuestra vida más fácil que nos permite
filtrar dependencias por su nombre, ronco-Express utiliza para iniciar el servidor web expresa a
través de gruñido y gruñido abierta para abrir direcciones URL / archivos de una tarea ronco.
Entonces, estos paquetes son todo acerca de la "infraestructura" y los ayudantes en los que
construiremos nuestra aplicación.
{
"name": "app",
"version": "1.0.0",
"dependencies": {},
"devDependencies": {
"grunt": "~0.4.1",
"matchdep": "~0.1.2",
https://riptutorial.com/es/home 223
"grunt-express": "~1.0.0-beta2",
"grunt-open": "~0.2.1"
},
"scripts": {
"postinstall": "bower install"
}
}
Bower.json
Bower es (o al menos debería ser) todo acerca del front-end y lo usaremos para instalar angular .
{
"name": "app",
"version": "1.0.0",
"dependencies": {
"angular": "~1.3.x"
},
"devDependencies": {}
}
gruntfile.js
Dentro de gruntfile.js tendremos la magia real de "aplicación local", que abre nuestra aplicación
en una nueva ventana del navegador, que se ejecuta en http: // localhost: 9000 /
'use strict';
// see http://rhumaric.com/2013/07/renewing-the-grunt-livereload-magic/
module.exports = function(grunt) {
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
grunt.initConfig({
express: {
all: {
options: {
port: 9000,
hostname: 'localhost',
bases: [__dirname]
}
}
},
open: {
all: {
path: 'http://localhost:<%= express.all.options.port%>'
}
}
});
grunt.registerTask('app', [
'express',
'open',
'express-keepalive'
]);
};
https://riptutorial.com/es/home 224
Uso
Para que su aplicación esté en funcionamiento desde cero, guarde los archivos anteriores en el
directorio raíz de su proyecto (cualquier carpeta vacía servirá). Luego, inicie la consola / línea de
comando y escriba lo siguiente para instalar todas las dependencias necesarias.
grunt app
Tenga en cuenta que sí, también necesitará sus archivos de aplicación reales.
Para un ejemplo casi mínimo, examine el repositorio de GitHub mencionado al principio de este
ejemplo.
La estructura no es tan diferente. Solo hay una plantilla index.html , código angular en app.js y
algunos estilos en app.css . Otros archivos son para configuración de Git y editor y algunas cosas
genéricas. ¡Darle una oportunidad!
https://riptutorial.com/es/home 225
Capítulo 50: Usando AngularJS con
TypeScript
Sintaxis
• $ scope: ng.IScope - esta es una forma en mecanografiado para definir el tipo para una
variable en particular.
Examples
Controladores angulares en mecanografiado
Los controladores se pueden hacer muy fácilmente utilizando las clases de escritura.
module App.Controllers {
class Address {
line1: string;
line2: string;
city: string;
state: string;
}
export class SampleController {
firstName: string;
lastName: string;
age: number;
address: Address;
setUpWatches($scope: ng.IScope): void {
$scope.$watch(() => this.firstName, (n, o) => {
//n is string and so is o
});
};
constructor($scope: ng.IScope) {
this.setUpWatches($scope);
}
}
}
El Javascript resultante es
var App;
(function (App) {
https://riptutorial.com/es/home 226
var Controllers;
(function (Controllers) {
var Address = (function () {
function Address() {
}
return Address;
}());
var SampleController = (function () {
function SampleController($scope) {
this.setUpWatches($scope);
}
SampleController.prototype.setUpWatches = function ($scope) {
var _this = this;
$scope.$watch(function () { return _this.firstName; }, function (n, o) {
//n is string and so is o
});
};
;
return SampleController;
}());
Controllers.SampleController = SampleController;
})(Controllers = App.Controllers || (App.Controllers = {}));
})(App || (App = {}));
//# sourceMappingURL=ExampleController.js.map
Después de hacer la clase de controlador, deje que el módulo angular js sobre el controlador se
pueda hacer simple usando la clase
app
.module('app')
.controller('exampleController', App.Controller.SampleController)
El controlador que hemos creado puede ser instanciado y usado usando el controller as Sintaxis.
Eso es porque hemos puesto la variable directamente en la clase del controlador y no en el $scope
.
Forma tradicional:
<div ng-controller="MyCtrl">
{{name}}
</div>
https://riptutorial.com/es/home 227
// we are using the "this" Object instead of "$scope"
app.controller('MyCtrl', function() {
this.name = 'John';
});
Entonces, ahora podemos usar la instancia jsObj para acceder a cualquier método o propiedad de
jsClass .
En angular, hacemos el mismo tipo de cosa. Usamos el controlador como sintaxis para la
instanciación.
La forma en que se inyecta $ scope en las funciones del constructor del controlador es una forma
de demostrar y usar la opción básica de inyección de dependencia angular, pero no está lista
para la producción ya que no se puede minimizar. Eso es porque el sistema de minificación
cambia los nombres de las variables y la inyección de dependencia de anguar utiliza los nombres
de los parámetros para saber qué se debe inyectar. Entonces, para un ejemplo, la función
constructora de ExampleController se reduce al siguiente código.
function n(n){this.setUpWatches(n)
y $scope se cambia a n !
para superar esto podemos agregar una matriz $ inject ( string[] ). De modo que la DI de angular
sabe qué inyectar en qué posición está la función de constructor de los controladores.
Así que el texto escrito arriba cambia a
module App.Controllers {
class Address {
line1: string;
line2: string;
city: string;
state: string;
}
export class SampleController {
firstName: string;
lastName: string;
age: number;
address: Address;
setUpWatches($scope: ng.IScope): void {
$scope.$watch(() => this.firstName, (n, o) => {
https://riptutorial.com/es/home 228
//n is string and so is o
});
};
static $inject : string[] = ['$scope'];
constructor($scope: ng.IScope) {
this.setUpWatches($scope);
}
}
}
Caso 1 :
Se crea en el controller object , no en $scope . Las vistas no pueden acceder a las funciones
definidas en el objeto controlador.
Ejemplo:
Caso 2:
Se crea en el $scope object , no en el controller object . Las vistas solo pueden acceder a las
funciones definidas en el objeto $scope .
Ejemplo:
https://riptutorial.com/es/home 229
diferentes en una página que están vinculados a {{name}} lo que es difícil identificar cuál es
de cuál controlador.
<div ng-controller="FirstCtrl">
{{ name }}
<div ng-controller="SecondCtrl">
{{ name }}
<div ng-controller="ThirdCtrl">
{{ name }}
</div>
</div>
</div>
Aquí, en el caso anterior, {{ name }} será muy confuso de usar y tampoco sabemos cuál está
relacionado con qué controlador.
https://riptutorial.com/es/home 230
Capítulo 51: Uso de directivas incorporadas.
Examples
Ocultar / Mostrar elementos HTML
<!DOCTYPE html>
<html ng-app="myDemoApp">
<head>
<script src="https://code.angularjs.org/1.5.8/angular.min.js"></script>
<script>
function HideShowController() {
var vm = this;
vm.show=false;
vm.toggle= function() {
vm.show=!vm.show;
}
}
Demo en vivo
https://riptutorial.com/es/home 231
9. ng-click directiva ng-click dispara una función de conmutación dentro del controlador
https://riptutorial.com/es/home 232
Capítulo 52: Validación de formularios
Examples
Validación básica de formularios
Una de las fortalezas de Angular es la validación de la forma del lado del cliente.
Tratar con las entradas de formularios tradicionales y tener que usar el procesamiento de estilo
jQuery interrogativo puede llevar mucho tiempo y ser complicado. Angular le permite producir
formas interactivas profesionales con relativa facilidad.
Para que Angular valide las entradas, use exactamente la misma sintaxis que un elemento de
entrada regular, a excepción de la adición del atributo ng-model para especificar a qué variable
vincular en el alcance. El correo electrónico se muestra en el ejemplo anterior. Para validar un
número, la sintaxis sería:
Los pasos finales para la validación de formularios básicos se conectan a una función de envío de
formularios en el controlador mediante ng-submit , en lugar de permitir que se realice el envío de
formularios predeterminado. Esto no es obligatorio pero generalmente se usa, ya que las
variables de entrada ya están disponibles en el alcance y, por lo tanto, están disponibles para su
función de envío. También suele ser una buena práctica dar un nombre al formulario. Estos
cambios darían lugar a la siguiente sintaxis:
Este código anterior es funcional pero hay otra funcionalidad que proporciona Angular.
El siguiente paso es comprender que Angular adjunta atributos de clase utilizando ng-pristine ,
ng-dirty , ng-valid y ng-invalid para el procesamiento de formularios. El uso de estas clases en
https://riptutorial.com/es/home 233
su css le permitirá diseñar campos de entrada válidos / no válidos y prístinos / sucios , y
alterar la presentación a medida que el usuario ingresa datos en el formulario.
Las formas y entradas angulares tienen varios estados que son útiles al validar el contenido
Estados de entrada
Estado Descripción
Todos los estados anteriores son propiedades booleanas y pueden ser verdaderas o falsas.
Aquí, estamos usando la directiva ng-show para mostrar un mensaje a un usuario si ha modificado
un formulario pero no es válido.
Clases de CSS
Angular también proporciona algunas clases de CSS para formularios y entradas dependiendo de
su estado
Clase Descripción
https://riptutorial.com/es/home 234
Clase Descripción
input.ng-invalid {
background-color: crimson;
}
input.ng-valid {
background-color: green;
}
ngMessages
ngMessages se usa para mejorar el estilo para mostrar mensajes de validación en la vista.
Enfoque tradicional
Antes de ngMessages , normalmente mostramos los mensajes de validación utilizando las directivas
angulares predefinidas ng-class . Este enfoque fue basura y una tarea repetitive .
Ejemplo
HTML:
<form name="ngMessagesDemo">
<input name="firstname" type="text" ng-model="firstname" required>
<div ng-messages="ngMessagesDemo.firstname.$error">
<div ng-message="required">Firstname is required.</div>
</div>
</form>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.16/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.16/angular-
messages.min.js"></script>
JS:
https://riptutorial.com/es/home 235
Validación de formularios personalizados
angular.module('app', [])
.directive('myValidator', function() {
return {
// element must have ng-model attribute
// or $validators does not work
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$validators.myValidator = function(modelValue, viewValue) {
// validate viewValue with your custom logic
var valid = (viewValue && viewValue.length > 0) || false;
return valid;
};
}
};
El validador se define como una directiva que requiere ngModel , por lo que para aplicar el
validador simplemente agregue la directiva personalizada al control de formulario de entrada.
<form name="form">
<input type="text"
ng-model="model"
name="model"
my-validator>
<pre ng-bind="'my-validator returned: ' + form.model.$valid"></pre>
</form>
Y my-validator no tiene que aplicarse en el control de forma nativo. Puede ser cualquier elemento,
siempre que sea ng-model en sus atributos. Esto es útil cuando tienes algún componente ui de
compilación personalizado.
Formularios anidados
A veces es conveniente anidar formularios con el fin de agrupar los controles y las entradas de
forma lógica en la página. Sin embargo, los formularios HTML5 no deben estar anidados.
Suministros angulares ng-form lugar.
https://riptutorial.com/es/home 236
<!-- show errors for the nested subform here -->
<div ng-messages="myForm.myNestedForm.$error">
<!-- note that this will show if either input does not meet the minimum -->
<div ng-message="minlength">Length is not at least 1</div>
</div>
</form>
Cada parte de la forma contribuye al estado general de la forma. Por lo tanto, si una de las
entradas myInput1 ha sido editada y está $dirty , su formulario que contiene también será $dirty .
Esto va en cascada a cada formulario que contiene, por lo que tanto myNestedForm como myForm
serán $dirty .
Validadores asíncronos
Los validadores asíncronos le permiten validar la información del formulario contra su backend
(utilizando $ http).
Este tipo de validadores son necesarios cuando necesita acceder a la información almacenada en
el servidor que no puede tener en su cliente por varios motivos, como la tabla de usuarios y otra
información de la base de datos.
Para usar los validadores asíncronos, acceda al ng-model de su input y defina las funciones de
devolución de llamada para la propiedad $asyncValidators .
Ejemplo:
Ahora, cada vez que se cambia el ng-model de la entrada, esta función se ejecutará y devolverá
una promesa con el resultado.
https://riptutorial.com/es/home 237
Creditos
S.
Capítulos Contributors
No
Almacenamiento de
3 Rohit Jindal
sesión
Cómo funciona el
7 Lucas L, Sasank Sunkavalli, theblindprophet
enlace de datos
10 Constantes Sylvain
https://riptutorial.com/es/home 238
Salaat, Mark Cidade, Matthew Green, Mike, Nad Flores,
Praveen Poonia, RamenChef, Sébastien Deprez, sgarcia.dev,
thegreenpizza, timbo, Und3rTow, WMios
Controladores con
12 Bouraoui KACEM
ES6
Directivas utilizando
18 Nikos Paraskevopoulos
ngModelController
El yo o esta variable
19 It-Z, Jim
en un controlador
Filtros
25 doodhwala, Pat, Sylvain
personalizados
https://riptutorial.com/es/home 239
Filtros
26 personalizados con Bouraoui KACEM
ES6
Funciones auxiliares
27 MoLow, Pranav C Balan, svarog
incorporadas
28 Impresión ziaulain
Migración a Angular
31 ShinDarth
2+
Opciones de enlaces
36 AngularJS (`=`, `@`, Alon Eitan, Lucas L, Makarov Sergey, Nico, zucker
`&` etc.)
Prepararse para la
39 JanisP
producción - Grunt
https://riptutorial.com/es/home 240
Proyecto Angular -
42 Estructura de jitender, Liron Ilayev
Directorio
Servicio Distinguido
45 Deepak Bansal
vs Fábrica
SignalR con
47 Maher
AngularJs
Usando AngularJS
50 Parv Sharma, Rohit Jindal
con TypeScript
Uso de directivas
51 Gourav Garg
incorporadas.
https://riptutorial.com/es/home 241