El término binding se emplea cuando nos referimos a conectar cosas de una manera que mantengan una sincronización entre estas. Y cuando digo conectar cosas, me refiero a la propiedad de un modelo con un campo de texto, por ejemplo. El data binding entre estos elementos hace que el input muestre el valor de la propiedad y al mismo tiempo el modelo almacene el valor insertado en el input.
Al tener una conexión en ambas direcciones, conseguimos que funcionen casi a tiempo a real. Me explico, cuando cambies el valor del input, la propiedad del modelo cambia inmediatamente después de haber introducido el valor pudiendo incluso mostrar su nuevo valor. Y por qué casi a tiempo real si parece que ocurre al instante? Porque para conseguir esto, Angularjs emplea algo llamado digest loop. Es un bucle que se activa cada vez que hay un cambio en algunos de los valores que angular está vigilando. Sin embargo, a ojos del usuario parecerá que funciona a tiempo real que es lo importante.
Cómo realizar data binding entre un input y el modelo
Para enlazar una propiedad del modelo a un input basta con emplear la directiva ng-model
1 |
<input type="text" name="nombre" ng-model="nombre"/> |
La directiva ng-model tiene como valor la propiedad del modelo que queremos vincular. Hay que tener en cuenta que en este proceso el objeto scope es muy importante. Esto se debe a que tanto en este ejemplo como en la normalidad, el objeto scope siempre es usado en el controlador. Cuando vinculamos «nombre» al input, lo que estamos vinculando es $scope.nombre.
Vamos a poner un ejemplo en marcha, comenzamos creando un módulo y su respectivo controlador.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// Creacion del modulo angular.module('moduloBinding', []); //Configurar el modulo con un controlador angular.module('moduloBinding').controller('controlador', function($scope) { var usuario = { nombre: "gc_user", contacto:{ movil:6000000, correo: "gc_user@hotmail.com", telefono: 900000000 } } $scope.usuario = usuario; }); |
En el controlador, creamos un objeto literal de usuario donde se guardará su nombre y sus medios de contactos (que es a su vez otro objeto literal).
Ahora que tenemos el código angularjs listo, vamos con el HTML donde realizaremos el data binding entre los campos de «nombre» y «móvil» con las propiedades del objeto usuario.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<div ng-app="moduloBinding"> <div ng-controller="controlador"> <form name="formulario"> <input type="text" name="nombre" ng-model="usuario.nombre"/><br/> <input type="text" name="movil" ng-model="usuario.contacto.movil"/> </form> <p> Nombre de usuario: {{usuario.nombre}} <br/> Número de móvil: {{usuario.contacto.movil}} </p> </div> </div> |
Además del formulario hay un párrafo con código angular que muestra el valor de las propiedades. El texto del párrafo irá cambiando en función de las propiedades del usuario que modifiquemos.
Si pones atención en la vinculación de la propiedad móvil, vemos que refleja una jerarquía ya que el objeto usuario tiene a su vez un objeto contacto con la propiedad móvil. Esta sería la forma de conseguir un data binding con las propiedades de un objeto anidado.
Resultado final
Qué es el two-way y one-way data binding
En este ejemplo además de vincular propiedades a un campo, también vemos 2 tipos de data binding. El que usamos en el formulario sería two-way data binding ya que es una vinculación recíproca, puedes modificar el valor de la propiedad desde el input y modificar el valor del campo cambiando el valor de la propiedad.
Luego en el párrafo llamamos a las propiedades del objeto usuario, ahí estamos realizando un one-way data binding. Se considera one-way o una vía ya que el usuario no puede modificar el valor y sólo muestra un texto plano. También podemos hacer este tipo de data binding sin necesidad de corchetes y emplear la directiva ng-bind en un elemento <span>.
1 2 3 4 |
<p> Nombre de usuario: <span ng-bind="usuario.nombre"></span> <br/> Número de móvil: <span ng-bind="usuario.contacto.movil"></span> </p> |
Hacer un data binding sin modelo
Cuando empleamos la directiva ngModel en ausencia de un propiedad de un modelo, AngularJS lo crea por ti. En esta ocasión el formulario tendrá un campo que se vinculara a una propiedad nombre, que no existe, y un botón que invocará una función que se centrará en mostrar el valor de la propiedad nombre en un alert.
1 2 3 4 5 6 7 8 |
<div ng-app="moduloBinding"> <div ng-controller="controlador"> <form name="formulario"> <input type="text" name="nombre" ng-model="nombre"/><br/> <input type="button" value="Mostrar nombre" ng-click="mostrarNombre()"/> </form> </div> </div> |
En el controlador, sólo habrá una función mostrarNombre() que mostrará el valor de la propiedad. No está el objeto usuario que hemos creado antes.
1 2 3 4 5 6 7 8 9 |
// Creacion del modulo angular.module('moduloBinding', []); //Configurar el modulo con un controlador angular.module('moduloBinding').controller('controlador', function($scope) { $scope.mostrarNombre = function(){ alert("El nombre es: " + $scope.nombre); } }); |
Si al cargar la página le damos al botón y hay ningún valor en el campo, en el alert indicará que el valor de la propiedad nombre es «undefined» lo cuál es normal. Sin embargo, si introducimos un valor y le damos al botón si se mostrará el valor introducido.
Si queremos que el usuario introduzca un valor en el campo en vez de mostrar un undefined, podemos comprobar si hay algún valor introducido.
1 2 3 4 5 6 7 |
$scope.mostrarNombre = function(){ if(angular.isDefined($scope.nombre)){ alert("El nombre es: " + $scope.nombre); }else{ alert("El campo está vacío, introduce un valor"); } } |
Comprobamos si el valor existe mediante la función angular.isDefined() que devuelve true en caso haber un valor, aunque sean espacios.
Y hasta aquí data binding en Angularjs, espero que os haya gustado. A seguir picando 🙂