Buceando en CanJS Parte 2

Esta es la segunda parte de una serie de tres partes que le enseñará cómo crear una aplicación de administrador de contactos en JavaScript usando CanJS y jQuery. Cuando haya terminado con este tutorial, tendrá todo lo que necesita para crear sus propias aplicaciones de JavaScript utilizando CanJS!

En la primera parte, creó los modelos, las vistas y los controles necesarios para mostrar los contactos y los dispositivos utilizados para simular un servicio REST.

En esta parte, usted:

  • Crea un control y una vista para mostrar categorías.
  • Escuchar eventos usando un control.
  • Usar enrutamiento para filtrar contactos.

Estarás agregando a los archivos de origen de la primera parte, así que si aún no lo has hecho, ponte al día primero. Estaré aquí cuando estés listo.


Configuración de enrutamiento

El enrutamiento ayuda a administrar el historial del navegador y el estado del cliente en aplicaciones JavaScript de una sola página.

El enrutamiento ayuda a administrar el historial del navegador y el estado del cliente en aplicaciones JavaScript de una sola página. El hash en la URL contiene propiedades que una aplicación lee y escribe. Varias partes de la aplicación pueden escuchar estos cambios y reaccionar en consecuencia, generalmente actualizando partes de la página actual sin cargar una nueva..

can.ruta Es un observable especial que actualiza y responde a los cambios en window.location.hash. Utilizar can.ruta para asignar direcciones URL a las propiedades, lo que resulta en direcciones URL bonitas como #! filtro / todo. Si no se definen rutas, el valor de hash simplemente se serializa en notación codificada en URL como #! category = all.

En esta aplicación, el enrutamiento se utilizará para filtrar contactos por categoría. Agregue el siguiente código a su contactos.js expediente:

 can.ruta ('filter /: category') can.ruta (", category: 'all')

La primera línea crea una ruta con un categoría Propiedad que tu aplicación podrá leer y escribir. La segunda línea crea una ruta por defecto, que establece la categoría propiedad a todos.


Trabajar con una lista de instancias modelo

UNA Modelo.Lista Es una matriz observable de instancias de modelos. Cuando definas un Modelo me gusta Contacto, una Modelo.Lista para ese tipo de modelo se crea automáticamente. Podemos extender esto creado. Modelo.Lista para agregar funciones de ayuda que operan en una lista de instancias de modelo.

Lista de contactos Necesitará dos funciones de ayuda para filtrar una lista de contactos e informar cuántos contactos hay en cada categoría. Añadir esto a contactos.js inmediatamente después de la Contacto modelo:

 Contact.List = can.Model.List (filter: function (category) this.attr ('length'); var contacts = new Contact.List ([]); this.each (function (contact, i)  if (category === 'all' || category === contact.attr ('category')) contacts.push (contact)) devolver contactos;, count: function (category) return this.filter (categoría) .length;);

Las dos funciones de ayuda aquí son:

  • filtrar() recorre cada contacto en la lista y devuelve un nuevo Lista de contactos de contactos dentro de una categoría. this.attr ('longitud') se incluye aquí, por lo que EJS configurará el enlace en vivo cuando usemos este asistente en una vista.
  • contar() devuelve el número de contactos en una categoría usando el filtrar() Función auxiliar. Porque this.attr ('longitud') en filtrar(), EJS configurará el enlace en vivo cuando usemos este helper en una vista.

Si va a utilizar un ayudante en EJS, use attr () en una lista o propiedad de instancia para configurar el enlace en vivo.


Filtrando contactos

A continuación, modificará la contactosLista.ejs Ver para filtrar contactos según la propiedad de categoría en el hash. En el contactosLista.ejs vista, cambiar el parámetro pasado a la lista() ayudante a contacts.filter (can.route.attr ('categoría')). Tu archivo EJS debería verse así cuando hayas terminado:

 
    <% list(contacts.filter(can.route.attr('category')), function(contact) %>
  • el.data ('contacto', contacto)% >>
    <%== can.view.render('contactView', contact: contact, categories: categories) %>
  • <% ) %>

En linea dos, filtrar() Se llama con la categoría actual desde can.ruta. Desde que usaste attr () en filtrar() y en can.ruta, EJS configurará el enlace en vivo para volver a generar su interfaz de usuario cuando cualquiera de estos cambios.

A estas alturas ya debería estar claro cuán poderosa es la unión en vivo. Con un ligero ajuste en su vista, la interfaz de usuario de la aplicación ahora estará completamente sincronizada no solo con la lista de contactos, sino también con la propiedad de categoría definida en la ruta..


Visualización de categorías

Los contactos se filtran cuando se modifica la propiedad de categoría en el hash. Ahora necesita una forma de enumerar todas las categorías disponibles y cambiar el hash.

Primero, cree una nueva Vista para mostrar una lista de categorías. Guarde este código como filterView.ejs en tus puntos de vista carpeta:

 
  • Categorías
  • Todos (<%= contacts.count('all') %>)
  • <% $.each(categories, function(i, category) %>
  • "><%= category.name %> (<%= contacts.count(category.data) %>)
  • <% ) %>

Repasemos algunas líneas de este código y veamos lo que hacen:

 <% $.each(categories, function(i, category) %>

$. cada Recorre las categorías y ejecuta una devolución de llamada para cada una..

 "><%= category.name %> (<%= contacts.count(category.data) %>

Cada enlace tiene una categoría de datos atributo que se insertará en el objeto de datos de jQuery. Más tarde, se puede acceder a este valor usando .datos ('categoría') sobre el etiqueta. El nombre de la categoría y el número de contactos se utilizarán como prueba de enlace. El enlace en vivo se configura en el número de contactos porque contar() llamadas filtrar() que contiene this.attr ('longitud').


Escuchando eventos con puede.control

El control enlaza automáticamente los métodos que parecen controladores de eventos cuando se crea una instancia. La primera parte del controlador de eventos es el selector y la segunda parte es el evento que desea escuchar. El selector puede ser cualquier selector CSS válido y el evento puede ser cualquier evento DOM o evento personalizado. Así que una función como 'un clic' escuchará un click en cualquier etiqueta dentro del elemento de control.

El control utiliza la delegación de eventos, por lo que no tiene que preocuparse por volver a vincular los controladores de eventos cuando cambia el DOM.


Visualización de categorías

Cree el control que administrará las categorías agregando este código a contactos.js justo después de la Contactos Controlar:

 Filter = can.Control (init: function () var category = can.route.attr ('category') || "all"; this.element.html (can.view ('filterView', contactos: este .options.contacts, categories: this.options.categories)); this.element.find ('[data-category = "' + category + '"]'). parent (). addClass ('active'); , '[data-category] click': function (el, ev) this.element.find ('[data-category]'). parent (). removeClass ('active'); el.parent (). addClass ('active'); can.route.attr ('category', el.data ('category')););

Examinemos el código del control 'Filtro' que acaba de crear:

 this.element.html (can.view ('filterView', contactos: this.options.contacts, categorías: this.options.categories));

Como en el Contactos Controlar, en eso() usos puedo ver() para representar categorías y html () Insertarlo en el elemento de Control..

 this.element.find ('[data-category = "' + category + '"]'). parent (). addClass ('active');

Encuentra el enlace que corresponde a la categoría actual y agrega una clase de 'activo' a su elemento principal.

 '[data-category] click': function (el, ev) 

Escucha un hacer clic evento en cualquier elemento que coincida con el selector [categoría de datos].

 this.element.find ('[data-category]'). parent (). removeClass ('active'); el.parent (). addClass ('activo');

Elimina la clase 'activa' de todos los enlaces y luego agrega una clase de 'activa' al enlace en el que se hizo clic.

 can.route.attr ('category', el.data ('category'));

Actualiza la categoría de propiedad en. can.ruta utilizando el valor del objeto de datos jQuery para el se hizo clic.


Inicializando el control de filtro

Al igual que el Contactos En la primera parte del control, debe crear una nueva instancia de Filtrar Controlar. Actualice su función de documento listo para verse así:

 $ (document) .ready (function () $ .when (Category.findAll (), Contact.findAll ()). then (function (categoryResponse, contactResponse) var categories = categoryResponse [0], contacts = contactResponse [0 ]; nuevos contactos ('# contactos', contactos: contactos, categorías: categorías); nuevo Filtro ('# filtro', contactos: contactos, categorías: categorías););)

Con este cambio, una instancia de la Filtrar El control se creará en el #filtrar elemento. Se pasará la lista de contactos y categorías..

Ahora, cuando ejecute su aplicación en un navegador, podrá filtrar contactos haciendo clic en las categorías de la derecha:


Terminando

¡Eso es todo para la segunda parte! Esto es lo que hemos logrado:

  • Creé un Control que escucha eventos y gestiona categorías.
  • Configurar enrutamiento para filtrar contactos por categoría
  • Modificó sus vistas para que el enlace en vivo mantenga su IU sincronizada con su capa de datos

En la tercera parte, actualizará sus controles existentes para permitir que los contactos se editen y eliminen. También creará un nuevo Control y Vista que le permitirá agregar nuevos contactos.

¿No puedo esperar para aprender más? La tercera parte de la serie ha sido publicada aquí.!