Introducción a Angular JS

Escuchando cambios en el scope usando el $watch Más videos

Descripción del tema

Seguiremos trabajando en la directiva que iniciamos en el tutorial anterior, hasta este momento ya tenemos el combobox usando el plugin de jQuery, pero no cuenta con opciones, en el tema de hoy vamos a agregar esas opciones de manera dinámica. Antes de entrar a ver el código debemos conocer ciertos conceptos importantes.

El Digest cycle

Cada que sucede algún evento dentro del browser's event loop, Angular JS ejecuta lo que se conoce como el Digest cycle, dentro de este ciclo se realizan dos tareas principales, en primer lugar se revisan los cambios en el scope para ejecutar la lista de propiedades que se están observando y también las que se pospondrán para ser procesadas más adelante de manera asíncrona.

Gracias a este mecanismo, es que podemos tener el two-day databinding, las directivas que usamos en nuestros templates verifican que ha sucedido un cambio y se actualizan las vistas. Generalmente no es necesario ejecutar el digest cycle de manera manual, pero cuando integramos plugins de jQuery o cualquier otra librería es necesario notificar cambios o eventos ocurridos en nuestros componentes a Angular.

El método $watch

En Angular podemos observar propiedades del scope para saber cuado han sido modificadas, de esta manera podemos realizar las operaciones necesarias.

Para vigilar una propiedad utilizamos el método $watch del scope que queremos observar, y definimos la función que se ejecutará cuando el valor de la propiedad cambie, este mecanismo es una de las partes fundamentales de Angular JS y es justo lo que necesitamos para seguir construyendo nuestra directiva.

En nuestro caso necesitamos estar observando el arreglo de categories, ya que necesitamos desplegar las opciones en el combobox con el arreglo que nos llega del servidor.

Para observar una propiedad en el scope lo hacemos de la siguiente manera. Dentro de la directiva que definimos en el tutorial anterior agregamos el siguiente código.

scope.$watch('categories',function(data){ //Step 1
    console.log(data);                    //Step 2
});
  1. En el primer paso utilizamos el método $watch del scope, este método es el responsable de observar la propiedad que definimos como primer parámetro, en este caso categories, el segundo parámetro es la función que se ejecutará cuando suceda algún cambio.
  2. El paso dos se ejecuta cuando el valor de categories cambia, esta función recibe como parámetro la nueva información.

Con eso estaremos observando los cambios en la propiedad categories. Algo importante comentar es que el método $watch únicamente observará cambios de referencia, es decir que me notificará cuando un nuevo arreglo sea asignado a categories, pero no me notificará si el actual arreglo ha sido modificado, por ejemplo si agregamos una nueva categoría o quitamos alguna del arreglo actual.

Si quisiéramos escuchar cambios sobre el arreglo usaríamos otro método, pero eso es otro tema que no tocaré en este tutorial ya que para nuestro ejemplo esto es suficiente, puesto que no estamos modificando el arreglo de categories.

Una vez que recibimos el arreglo de categories desde el servidor, necesitamos agregar las opciones al select de la siguiente manera.

scope.$watch(collection,function(data){  //Step 1
    if(data){                            //Step 2
        $(element)
            .find('option')
            .remove();                   //Step 3

        var html = [];
        $.each(data, function(index, object) {  //Step 4
            html.push('<option value="'+object[valueProperty]+'">');
            html.push(object[labelProperty]);
            html.push('</option>');
        });
        $(element).append(html.join(''));
        $(element).selectpicker('refresh');   //Step 5
    }
});
  1. En el paso uno solamente estamos usando una variable, en el tutorial anterior la definimos para que dinámicamente seleccionemos la colección desde nuestro template.
  2. En el segundo paso verificamos que la nueva información contenga algo, esto es en caso de recibir un valor nulo.
  3. En el paso tres eliminamos las opciones anteriores del select.
  4. En el cuarto paso creamos las opciones utilizando la propiedad value y label que configuramos en el template, esas variables las definimos en el tutorial anterior, también las agregamos al select usando jQuery.
  5. En el último paso refrescamos el select picker para que refleje los nuevos cambios en el select original.

Con esto es suficiente, si probamos nuestros cambios veremos que el select cuenta con las categorías que vienen desde el servidor.

Combo con Angular JS

Combo en Angular JS

Como se puede observar hay un pequeño detalle en el CSS, pareciera ser que el z-index no es correcto, pero fuera de eso ya tenemos las opciones en el select de manera dinámica, usando una directiva para integrar el plugin de jQuery.

Para arreglar el problema necesitamos definir el siguiente CSS en la hoja de estilos.

.category-cmb-field{
  z-index:3;
}

Y luego agregar esa clase al grupo del field categories en el template. 

<div class="form-group">
  <label for="category">Category</label>
  <div class="input-group category-cmb-field">
    <div class="input-group-addon">
      <i class="glyphicon glyphicon-folder-open"></i>
    </div>
    <select bootstrap-select="categories" select-value="id" select-label="name" ng-model="bookmark.category" class="form-control"></select>
    <!-- <select ng-model="bookmark.category" ng-options="obj.name for obj in categories track by obj.id" id="category" class="form-control"> -->
    </select>
  </div>
</div>

Con eso estará solucionado el problema.

Directiva en Angular JS

Directiva para un combo en Angular JS

Ahora si se ve genial nuestro componente, todavía no esta terminado pero ya estamos cerca.

Hasta aquí llegaremos en este tutorial, hemos visto como funciona el digest cycle y como observar los cambios sobre alguna propiedad del scope. En el siguiente tutorial veremos como asignar el valor seleccionado usando el ngModel.

Si te ha gustado este tutorial por favor compártelo en tus redes sociales favoritas, eso me ayudará mucho a seguir publicando mas contenido de forma gratuita.

Te gustaría recibir más tutoriales como este en tu correo?

Este tutorial pertenece al curso Introducción a Angular JS, te recomiendo revises el resto de los tutoriales ya que están en secuencia de menor a mayor complejidad.

Si deseas recibir más tutoriales como este en tu correo te recomiendo registrarte al curso, si ya eres miembro solo identifícate y registrate al curso, si no eres miembro te puedes registrar gratuitamente!

Si no gustas registrarte en este momento no es necesario! Aún así puedes recibir los nuevos tutoriales en tu correo! Jamás te enviaremos Spam y puedes cancelar tu suscripción en cualquier momento.

¿Olvidaste tu contraseña?

5Comentarios

  • Avatar-12 Jorge Armand Olivero 14/11/2014

    Bien

    • Avatar-9 edwing david romero 26/11/2014

      Esta parte si que no la entendi ... la volvere a ver.. jjejeje

    • Avatar-7 JamoDev 13/08/2015

      Hola, estoy atascado en algo en mi proyecto y no se como hacerlo, la cuestion es que quiero a partir de unos datos que llegan del servidor poblar un formulario en los input text no hay problema pero en el select le mando el dato al ng-model pro el select no cambia. pd el select lo estoy poblando con otros datos que llegan del server

      • Avatar-11 christian 09/02/2017

        puedes agregar un video de pagination en angular y boostrap utilizando este ejecicio

        Instructor del curso

        Crysfel3

        Autor: Crysfel Villa

        Ha participado en varios proyectos con Angular y es participante activo del grupo de Angular NYC.

        Descarga video Descarga Código Fuente Ver Demostración

        Regístrate a este curso

        Este tutorial pertenece al curso Introducción a Angular JS, revisa todos los tutoriales que tenemos en este mismo curso ya que están en secuencia y van de lo más sencillo a lo más complicado.

        Tendrás acceso a descargar los videos, códigos y material adicional.

        Podrás resolver los ejercicios incluidos en el curso así como los Quizzes.

        Llevarás un registro de tu avance.