Utilice Backbone.js para acelerar las interacciones

Autor: Monica Porter
Fecha De Creación: 13 Marcha 2021
Fecha De Actualización: 15 Mayo 2024
Anonim
⚡ VITE: ¿Cómo funciona el empaquetador Javascript más rápido?
Video: ⚡ VITE: ¿Cómo funciona el empaquetador Javascript más rápido?

Contenido

Si está buscando crear rápidamente una pequeña herramienta de JavaScript, probablemente no esté pensando en usar un marco. Es más fácil hackear un poco de código jQuery en lugar de instalar y aprender un nuevo marco, ¿verdad? Incorrecto, Backbone.js es un marco de pegamento superligero que se parece al JavaScript antiguo normal que estás acostumbrado a escribir.

Hacemos muchos prototipos estáticos aquí en ZURB, porque nos gusta poder hacer clic en las páginas sin tener que escribir ningún código de backend. A menudo, solíamos colocar imágenes de marcador de posición grises monótonas, o, a veces, íbamos a buscar en Flickr imágenes de muestra para ayudarnos a visualizar lo que podría ir en el borrador final. Eso fue hasta un viernes mágico, cuando decidimos que sería genial escribir algo de JavaScript para resolver nuestros problemas. Queríamos poder buscar y seleccionar fotos en Flickr, directamente desde las propias imágenes de marcador de posición. Lo llamaríamos FlickrBomb, y esta es la historia de cómo lo construimos usando Backbone.js.


Se recomienda encarecidamente que eche un vistazo rápido a FlickrBomb antes de leer. Es una de esas ofertas del tipo "un clic vale más que mil palabras". Adelante, esperaremos.

Hay muchos marcos de JavaScript en el bloque en estos días, SproutCore, JavaScriptMVC, Spine, Sammy, Knockout. Pero nos gustó Backbone.js para este proyecto en particular por diferentes razones:

1. Es ligero (de hecho, 100% libre de grasas)

  • de peso, con la última versión empaquetada de aproximadamente 4,6 kb
  • en código, al tener poco más de 1000 líneas de código, no es muy difícil seguir el rastro de una pila hasta el interior sin perder la cabeza

2. Parece JavaScript

  • porque es JavaScript, eso es todo y eso es todo
  • usa jQuery, que incluso tu abuela conoce en estos días

3. Persistencia súper simple


  • Fuera de la caja, conserva los datos en un backend (a través de REST), pero al colocar un solo complemento, se guardará en el almacenamiento local.
  • debido a que abstrae la API de persistencia, podríamos hacer que persista en un backend REST simplemente eliminando el complemento de almacenamiento local

Empecemos entonces

Debido a que Backbone.js es solo JavaScript, todo lo que tenemos que hacer es incluirlo junto con Underscore.js en la página. jQuery no es una dependencia estricta para Backbone per se, pero lo usaremos, así que lo incluiremos aquí. También vincularemos el complemento de almacenamiento local, ya que no queremos molestarnos con configurar un backend. Tenga en cuenta que estamos vinculando directamente los archivos aquí para simplificar, pero siempre debe alojar sus propios activos en producción.

script src = "http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"> / script> script src = "http://documentcloud.github.com/backbone/ backbone-min.js "> / script> script src =" http://documentcloud.github.com/underscore/underscore-min.js "> / script> script src =" https://raw.github.com/ jeromegn / Backbone.localStorage / master / backbone.localStorage-min.js "> / script>

Todo el código siguiente en este artículo es específico de nuestra aplicación, por lo que podemos incluirlo en un archivo app.js, o simplemente en línea si eso es lo tuyo. Solo recuerde incluirlo después de Backbone. Backbone permite abstraer partes de nuestra aplicación, para hacerlas modulares para una fácil reutilización y más legibles para otros. Para ilustrar mejor esa abstracción, íbamos a explicar el diseño de FlickrBomb de abajo hacia arriba, comenzando con los modelos y terminando con las vistas.


Nuestro primer modelo

La primera tarea que vamos a abordar es sacar las fotos de Flickr. Modelar una FlickrImage en la red troncal es bastante simple, crearemos un nuevo modelo llamado FlickrImage y agregaremos algunos métodos para ayudarnos a obtener pulgares de diferentes tamaños.

var FlickrImage = Backbone.Model.extend ({fullsize_url: function () {return this.image_url ('medium');}, thumb_url: function () {return this.image_url ('square');}, image_url: function ( size) {var size_code; switch (size) {case 'square': size_code = '_s'; break; // 75x75 case 'medium': size_code = '_z'; break; // 640 en el caso lateral más largo 'large ': size_code =' _b '; break; // 1024 en el lado más largo predeterminado: size_code =' ';} return "http: // farm" + this.get (' farm ') + ".static.flickr.com / "+ this.get ('servidor') +" / "+ this.get ('id') +" _ "+ this.get ('secreto') + size_code +" .webp ";}})

Los modelos en Backbone son objetos que pueden persistir y tienen algunas funciones asociadas con ellos, al igual que los modelos en otros marcos MVC. La parte mágica de los modelos Backbone es que podemos vincular eventos a atributos, de modo que cuando ese atributo cambie, podamos actualizar nuestras vistas para reflejarlo. Pero nos estamos adelantando un poco.

Cuando extraemos las fotos de Flickr, obtendremos suficiente información para crear URL para todos los tamaños. Sin embargo, ese ensamblaje queda en nuestras manos, por lo que implementamos la función .image_url () que toma un parámetro de tamaño y devuelve un enlace público. Debido a que este es un modelo de red troncal, podemos usar this.get () para acceder a los atributos del modelo. Entonces, con este modelo, podemos hacer lo siguiente en otra parte del código para obtener la URL de una imagen de Flickr.

flickrImage.image_url ('grande')

Bastante conciso, ¿eh? Dado que este modelo es específico para nuestra aplicación, agregaremos algunas funciones de envoltura para los tamaños de imagen de tamaño completo y pulgar.

Una colección de imágenes

FlickrBomb se ocupa de colecciones de imágenes, no de imágenes individuales, y Backbone tiene una forma conveniente de modelar esto. La colección con el nombre adecuado es lo que usaremos para agrupar imágenes de Flickr juntas para un único marcador de posición.

var FlickrImages = Backbone.Collection.extend ({model: FlickrImage, key: flickrbombAPIkey, page: 1, fetch: function (keywords, success) {var self = this; success = success || $ .noop; this.keywords = keywords || this.keywords; $ .ajax ({url: 'http://api.flickr.com/services/rest/', datos: {api_key: self.key, formato: 'json', método: 'flickr. photos.search ', etiquetas: this.keywords, per_page: 9, page: this.page, license: flickrbombLicenseTypes}, dataType:' jsonp ', jsonp:' jsoncallback ', éxito: función (respuesta) {self.add (respuesta .photos.photo); success ();}});}, nextPage: function (callback) {this.page + = 1; this.remove (this.models); this.fetch (null, callback);}, prevPage: function (callback) {if (this.page> 1) {this.page - = 1;} this.remove (this.models); this.fetch (null, callback);}});

Hay un par de cosas a tener en cuenta aquí. En primer lugar, el modelo El atributo le dice a las colecciones qué tipo de modelo está recolectando. También tenemos algunos atributos que inicializamos para usarlos más tarde: la clave es nuestra clave de API de Flickr, querrá reemplazar flickrbombAPIkey con la cadena de su propia clave de API de Flickr. Obtener una clave API de Flickr es gratis y fácil, solo siga este enlace: www.flickr.com/services/api/misc.api_keys.html. El atributo de página es la página actual de las fotos de Flickr en las que estamos.

El gran método aquí es .fetch (), que abstrae los detalles de extraer fotos de la API de Flickr. Para evitar problemas con las solicitudes entre dominios, usamos JSONP, que es compatible con la API de Flickr y jQuery. Los otros parámetros que estamos pasando a la API deberían ser autoexplicativos. De especial interés son las funciones de Backbone que se llaman aquí. En la devolución de llamada exitosa, usamos .add (), una función que toma una matriz de atributos de modelo, crea instancias de modelo a partir de esos atributos y luego las agrega a la colección.

Las funciones .nextPage () y .prevPage () primero cambian la página que queremos mostrar,
use la función de colección .remove (), para eliminar todos los modelos existentes de la
colección, y luego llamar a buscar para obtener las fotos de la página actual (que solo
cambió).

FlickrBombImage

Volviendo a subir, necesitamos un modelo más para representar la imagen del marcador de posición, que consistirá en una colección de FlickrImages y la FlickrImage actual que se ha seleccionado. A este modelo lo llamaremos FlickrBombImage.

var localStorage = (supports_local_storage ())? new Store ("flickrBombImages"): null; var FlickrBombImage = Backbone.Model.extend ({localStorage: localStorage, initialize: function () {_.bindAll (this, 'loadFirstImage'); this.flickrImages = new FlickrImages (); this.flickrImages.fetch (this.get ('palabras clave'), this.loadFirstImage); this.set (id: this.get ("id")); this.bind ('change: src', this.changeSrc) ;}, changeSrc: function () {this.save ();}, loadFirstImage: function () {if (this.get ('src') === undefined) {this.set ({src: this.flickrImages. first (). image_url ()});}}});

Dado que este modelo es responsable de realizar un seguimiento de la imagen seleccionada actualmente entre cargas de página, necesita saber qué tienda de almacenamiento local utilizar.La primera línea asegurará que haya soporte para almacenamiento local, y luego creará la tienda que usaremos para conservar la imagen seleccionada.

Backbone nos permite definir una función .initialize () que será llamada cuando se cree una instancia del modelo. Usamos esta función en FlickrBombImage para crear una nueva instancia de la colección FlickrImages, pasar las palabras clave que se usarán para esta imagen y luego buscar las imágenes de Flickr.

La función .loadFirstImage () se ha pasado como una devolución de llamada para que se ejecute cuando las imágenes se hayan cargado desde Flickr. Como probablemente pueda adivinar, esta función establece que la imagen actual sea la primera de la colección de Flickr. No hace esto si la imagen actual ya se ha configurado.

También usaremos las devoluciones de llamada de atributos de Backbone para activar nuestra función .changeSrc () cuando cambie el atributo src de este modelo. Todo lo que hace esta devolución de llamada es llamar .save (), una función del modelo Backbone que conserva los atributos del modelo en cualquier capa de tienda que se haya implementado (en nuestro caso, localstore). De esta manera, cada vez que se cambia la imagen seleccionada, se conserva inmediatamente.

La capa de vista

Ahora que tenemos todo el código de backend (bueno, frontend backend) escrito, podemos juntar las Vistas. Las vistas en Backbone son un poco diferentes a las vistas en otros marcos MVC tradicionales. Mientras que una vista normalmente solo se ocupa de la presentación, una vista troncal también es responsable del comportamiento. Eso significa que su Vista no solo define cómo se ve algo, sino también qué debe hacer cuando se interactúa con él.

Una vista está comúnmente (pero no siempre) vinculada a algunos datos y pasa por tres fases para generar el marcado de presentación a partir de esos datos:

1. Se inicializa el objeto Ver y se crea un elemento vacío.
2. Se llama a la función de renderizado, generando el marcado para la vista insertándolo en el elemento creado en el paso anterior.
3. El elemento está adjunto al DOM.

Esto puede parecer mucho trabajo para generar algunas marcas, y ni siquiera estamos en la parte de comportamiento de la Vista todavía, pero es importante, y este es el motivo. Cada vez que modifica elementos que están en el DOM, activa algo llamado redistribución del navegador. Un reflujo es el navegador recalculando cómo se posiciona todo en la página. Los reflujos del navegador pueden ser perjudiciales para el rendimiento si se llaman dentro de un evento de arrastre o cambio de tamaño, que se activa en un intervalo muy corto, pero peor aún, se ven descuidados. Con la manipulación compleja de la página, puede ver los elementos que se agregan a la página y el reposicionamiento de los elementos afectados. Siguiendo el patrón de Backbone de inicializar, renderizar y adjuntar, garantizas un único reflujo y los cambios en la página serán perceptiblemente instantáneos, independientemente de la complejidad de la manipulación de elementos.

El FlickrBombImageView

var FlickrBombImageView = Backbone.View.extend ({tagName: "div", className: "flickrbombContainer", lock: false, template: _.template ('div id = "% = this.image.id.replace (" ", "")%> "... / div> '), initialize: function (options) {_.bindAll (this,' addImage ',' updateSrc ',' setDimentions ',' updateDimentions '); var palabras clave = opciones. img.attr ('src') .replace ('flickr: //', ''); this. $ el = $ (this.el); this.image = new FlickrBombImage ({palabras clave: palabras clave, id: opciones. img.attr ('id')}); this.image.flickrImages.bind ('agregar', this.addImage); this.image.bind ('change: src', this.updateSrc);}, eventos: { "click .setupIcon": "clickSetup", "click .flickrbombFlyout a.photo": "selectImage", "click .flickrbombFlyout a.next": "nextFlickrPhotos", "click .flickrbombFlyout a.prev": "prevFlickrPhotos"}, render: function () {$ (this.el) .html (this.template ()); this.image.fetch (); this.resize (); return this;}, ...});

Las funciones de esta vista se han omitido por brevedad, el código fuente en su totalidad está disponible en GitHub: github.com/zurb/flickrbomb

En la parte superior de la Vista, tenemos un par de atributos específicos de Backbone. tagName y className se utilizan para definir la etiqueta y la clase que se aplicarán al elemento de esta vista. Recuerde que el paso uno de la creación de la vista es crear un objeto, y dado que esa creación es manejada por Backbone, necesitamos especificar el elemento y la clase. Tenga en cuenta que Backbone tiene valores predeterminados sensibles; si omitimos estos atributos, se usa un div de forma predeterminada y no se aplicará ninguna clase a menos que especifique una.

El atributo de plantilla es una convención, pero no es obligatorio. Lo estamos usando aquí para especificar la función de plantilla de JavaScript que usaremos para generar nuestro marcado para esta vista. Usamos la función _.template () incluida en Underscore.js, pero puede usar cualquier motor de plantillas que prefiera, no lo juzgaremos.

En nuestra función .initialize (), extraemos la cadena de palabras clave de la etiqueta de la imagen y luego creamos un modelo FlickrBombImage usando esas palabras clave. También vinculamos la función .addImage () para que se ejecute cuando se agrega una FlickrImage a la colección FlickrImages. Esta función agregará la FlickrImage recién agregada a nuestro menú lateral selector de imágenes. La última y más importante línea es vincular la función .updateSrc () para que se active cuando se cambia la FlickrImage actualmente seleccionada. Cuando se cambia la imagen actual en el modelo, esta función se ejecutará, actualizará el atributo src del elemento de imagen y CSS cambiará el tamaño y recortará la imagen para que se ajuste a las dimensiones de la imagen especificadas por el usuario.

eventos: {"click .setupIcon": "clickSetup", "click .flickrbombFlyout a.photo": "selectImage", "click .flickrbombFlyout a.next": "nextFlickrPhotos", "click .flickrbombFlyout a.prev": "prevFlickrPhotos "}

Después de .initialize () tenemos la parte de comportamiento de la Vista. Backbone proporciona una forma conveniente de vincular eventos mediante un objeto de eventos. El objeto de eventos usa el método jQuery .delegate () para hacer el enlace real al elemento Ver, de modo que independientemente de la manipulación que haga al elemento dentro de la vista, todos sus eventos enlazados seguirán funcionando. Funciona igual que jQuery .live (), excepto que en lugar de vincular eventos a todo el documento, puede vincularlos dentro del alcance de cualquier elemento. La clave de cada entrada en el objeto de eventos consiste en el evento y el selector, el valor indica la función que debe estar vinculada a ese evento. Tenga en cuenta que .delegate () no funciona con algunos eventos como enviar, consulte la documentación de jQuery .live () para obtener una lista completa de los eventos admitidos.

render: function () {$ (this.el) .html (this.template ()); this.image.fetch (); this.resize (); devuelve esto;}

Por último, tenemos la función .render () que es responsable de crear nuestro marcado y realizar cualquier trabajo adicional que no se pueda realizar hasta que el marcado Ver se haya agregado al elemento Ver. Después de renderizar nuestra plantilla, necesitamos llamar a .fetch () en nuestra FlickrBombImage. .fetch () es una función Backbone que obtiene la última copia del modelo de la capa de persistencia. Si hubiéramos guardado este modelo antes, .fetch () recuperaría esos datos ahora. Una vez que se ha obtenido la imagen, debemos llamar a resize para colocarla correctamente.

El estiramiento de casa

Con todas las piezas en su lugar, todo lo que tenemos que hacer ahora es encontrar las imágenes de marcador de posición en la página y reemplazarlas con las vistas de FlickrBombImage renderizadas.

$ ("img [src ^ = 'flickr: //']") .each (function () {var img = $ (this), flickrBombImageView = new FlickrBombImageView ({img: img}); img.replaceWith (flickrBombImageView. render (). el);});

Este pequeño recorte debe ejecutarse en la parte inferior de la página, o en una devolución de llamada lista para documentos, para asegurarse de que pueda encontrar las imágenes de marcador de posición que reemplazará. Usamos la convención de especificar flickr: // [KEYWORD] en el atributo src de una etiqueta de imagen para indicar que debe llenarse con imágenes de Flickr. Encontramos elementos de imagen con un atributo src coincidente, creamos un nuevo FlickrBombImageView y luego reemplazamos la imagen con la nuestra. Tomamos una copia de la imagen original y la pasamos a nuestro FlickrBombView, para que podamos extraer algunas opciones de configuración adicionales que pueden haber sido especificadas en el elemento.

El resultado final de todo ese arduo trabajo es una API muy simple para las personas que usan la biblioteca. Simplemente pueden definir etiquetas de imagen usando la convención flickr: //, colocar el código FlickrBomb en la parte inferior de su página y, bam, tienen imágenes de marcador de posición de Flickr.

También funciona muy bien con las grandes aplicaciones web

Tenemos una gran aplicación web llamada Notable, que fue escrita sin preocuparse por generar contenido en el lado del cliente. Cuando queríamos hacer que las secciones de la aplicación se recargaran generando contenido del lado del cliente, elegimos Backbone. Las razones eran las mismas: queríamos un marco ligero para ayudar a mantener el código organizado, pero que no nos obligara a repensar toda la aplicación.

Lanzamos los cambios a principios de este año con gran éxito, y desde entonces hemos estado cantando alabanzas a Backbones.

Recursos adicionales

Backbone es mucho más de lo que cubrí en este artículo, la parte C (controlador) de MVC (controlador de vista de modelo) para empezar, que en realidad es un R (enrutador) en la última versión. Y todo está cubierto en la documentación de Backbone, una ligera mañana de sábado decía:
documentcloud.github.com/backbone/

Si lo tuyo son los tutoriales más tradicionales, entonces echa un vistazo al código muy bien documentado de esta aplicación de todo escrito en Backbone:
documentcloud.github.com/backbone/docs/todos.html

Elección De Lectores
16 magníficos sitios web con fondos de video
Lee Mas

16 magníficos sitios web con fondos de video

Di eñar un itio web no ignifica que tenga que crear una experiencia e tática, no e imprime. Con el auge de HTML5, e má fácil agregar elemento como animación para crear una exp...
Las 10 mejores herramientas de maquetas web de 2015
Lee Mas

Las 10 mejores herramientas de maquetas web de 2015

La maqueta on un documento vi ual, que varía de media a alta fidelidad y apuntan a un píxel perfecto tanto como ea po ible, y práctico de de el punto de vi ta del de arrollador.Para ayu...
Consejos profesionales de WordPress y 11 fantásticos complementos
Lee Mas

Consejos profesionales de WordPress y 11 fantásticos complementos

Cuando comencé con el di eño de itio web, la opcione eran limitada . En u mayor parte, lo codificamo a mano. Hicimo e to en un editor de texto imple o en un IDE, como Dreamweaver.Hoy en d...