lec 2- array declaration and initialization.pptxshiks1234
This document discusses arrays, which are a fixed-size collection of elements of the same data type that share a common name. It describes one-dimensional arrays, which use a single index, and two-dimensional arrays, which represent data in rows and columns using two indices. The key points are: Arrays allow representing lists of data and can be initialized at compile-time or run-time; one-dimensional arrays use a single subscript while two-dimensional arrays use two subscripts to reference elements; memory for multi-dimensional arrays is stored in row-major order with the first index varying fastest.
Java beans are reusable software components that follow conventions like having a no-arg constructor and getter and setter methods. JSP allows for rapidly developing dynamic web pages and features like platform independence, an extensible tag library, and reusability. To deploy a Java bean in a JSP page, the bean is first constructed, then it can be accessed and used within JSP tags and scriptlets during page processing by the JSP engine.
The document discusses expression trees and algorithms for evaluating postfix, infix, and constructing binary expression trees. It explains that a binary expression tree represents a mathematical expression where each leaf node contains an operand and each non-leaf node contains an operator. The tree shows the order of operations based on the level of each node. The algorithms for evaluating infix and constructing the tree are similar except that pointers to nodes are pushed onto the stack instead of values.
The document discusses server-side and client-side state management in PHP. It explains that PHP uses sessions for server-side state management, storing user information on the server, while cookies are used for client-side state management by storing data on the user's browser. The document provides details on how to use sessions and cookies in PHP, including how to start sessions, access session variables, update and destroy sessions, and how to create, update, and delete cookies.
Nhận viết luận văn đại học, thạc sĩ trọn gói, chất lượng, LH ZALO=>0909232620
Tham khảo dịch vụ, bảng giá tại: https://vietbaitotnghiep.com/dich-vu-viet-thue-luan-van
Khóa luận tốt nghiệp: Hoàn thiện hệ thống kênh phân phối sản phẩm thiết bị vệ sinh tại Công ty TNHH Phát Đạt trên địa bàn tỉnh Thừa Thiên Huế, cho các bạn tham khảo
lec 2- array declaration and initialization.pptxshiks1234
This document discusses arrays, which are a fixed-size collection of elements of the same data type that share a common name. It describes one-dimensional arrays, which use a single index, and two-dimensional arrays, which represent data in rows and columns using two indices. The key points are: Arrays allow representing lists of data and can be initialized at compile-time or run-time; one-dimensional arrays use a single subscript while two-dimensional arrays use two subscripts to reference elements; memory for multi-dimensional arrays is stored in row-major order with the first index varying fastest.
Java beans are reusable software components that follow conventions like having a no-arg constructor and getter and setter methods. JSP allows for rapidly developing dynamic web pages and features like platform independence, an extensible tag library, and reusability. To deploy a Java bean in a JSP page, the bean is first constructed, then it can be accessed and used within JSP tags and scriptlets during page processing by the JSP engine.
The document discusses expression trees and algorithms for evaluating postfix, infix, and constructing binary expression trees. It explains that a binary expression tree represents a mathematical expression where each leaf node contains an operand and each non-leaf node contains an operator. The tree shows the order of operations based on the level of each node. The algorithms for evaluating infix and constructing the tree are similar except that pointers to nodes are pushed onto the stack instead of values.
The document discusses server-side and client-side state management in PHP. It explains that PHP uses sessions for server-side state management, storing user information on the server, while cookies are used for client-side state management by storing data on the user's browser. The document provides details on how to use sessions and cookies in PHP, including how to start sessions, access session variables, update and destroy sessions, and how to create, update, and delete cookies.
Nhận viết luận văn đại học, thạc sĩ trọn gói, chất lượng, LH ZALO=>0909232620
Tham khảo dịch vụ, bảng giá tại: https://vietbaitotnghiep.com/dich-vu-viet-thue-luan-van
Khóa luận tốt nghiệp: Hoàn thiện hệ thống kênh phân phối sản phẩm thiết bị vệ sinh tại Công ty TNHH Phát Đạt trên địa bàn tỉnh Thừa Thiên Huế, cho các bạn tham khảo
El documento describe un proyecto de construcción de un sistema de riego por aspersión en el sector Cusi de la comunidad campesina de Arahuara. Se realizará un estudio de impacto ambiental del proyecto que incluye la identificación de posibles problemas ambientales y medidas de mitigación. El estudio analizará los aspectos legales, describirá los componentes ambientales del área y evaluará los posibles impactos durante la construcción y operación. Finalmente, propondrá un plan de manejo ambiental y estimará los costos de las medidas de mitigación.
El documento presenta los estudios básicos y el planteamiento hidráulico para el proyecto de construcción de un sistema de riego por aspersión en el sector Cusi de la comunidad campesina de Arahuara. Los estudios incluyen levantamientos topográficos, características geológicas y mecánica de suelos. El planteamiento hidráulico propone una red de distribución con 42 hidrantes para regar 9.3 hectáreas con un caudal de 7 litros por segundo. Se describen las estructuras de captación
This document summarizes a meetup on authentication with Devise and OmniAuth. Devise is an authentication solution distributed as a Ruby gem that provides modules for password confirmation, recovery, and locking. OmniAuth allows for multi-provider authentication through strategies like Facebook and Twitter, and integrates with Devise using the OmniAuthable module. The meetup goals were to set up basic authentication with Devise, add useful modules, and integrate OmniAuth to allow logging in with a platform of choice. A live coding demo was provided from a GitHub repository.
El documento describe los pasos para realizar mantenimiento preventivo a un equipo. Primero se pasa un pincel seco por el emisor y receptor láser para quitar el polvo. Luego se aplica un chorro de aire comprimido para remover más polvo. Finalmente, se limpian los separadores en la base con algodón o paño humedecido en alcohol para retirar la suciedad.
El documento resume las teorías evolutivas de Darwin y Lamarck. Darwin sostenía que la evolución ocurre a través de la variabilidad entre individuos y la selección natural de las variaciones ventajosas. Lamarck creía que los cambios en el ambiente provocan el uso y desuso de órganos, los cuales se heredan y conducen a la evolución. Mientras que para Darwin la supervivencia de las variaciones aleatorias conduce a la evolución, Lamarck pensaba que el uso y desuso de los órganos impulsados por
La redacción jurídica desempeña un papel fundamental; de su eficacia dependen los resultados de los documentos elaborados para lograr los propósitos legales y/o comerciales. Los textos jurídicos están estrechamente ligados al ejercicio de la argumentación, propio de quienes trabajan en el campo del derecho y la jurisprudencia.
Este seminario-taller está enfocado a conocer y aplicar la estructura argumentativa de los textos jurídicos para su comprensión y redacción, de acuerdo con las herramientas que ofrecen la cohesión, la coherencia y demás elementos gramaticales que componen la lógica textual.
Este documento resume el proceso para la constitución y operación de una sociedad mercantil en Venezuela. Explica los pasos para reservar un nombre, constituir formalmente la sociedad mediante la inscripción de documentos en el Registro Mercantil, realizar asambleas de accionistas, transferir el fondo de comercio, disolver la sociedad y liquidarla. También incluye un modelo de estatutos para una sociedad anónima.
Este documento presenta varios métodos y estrategias para la enseñanza y el aprendizaje centrados en el estudiante, incluido el aprendizaje cooperativo, proyectos, webquests, aprendizaje basado en problemas y portafolios. También discute la importancia de que las escuelas funcionen como organizaciones que aprenden a través de la colaboración entre profesores y el desarrollo de una visión compartida.
Jazz originated in New Orleans in the late 19th century, developing from African rhythms played in Congo Square. Ragtime, with its syncopated rhythms, evolved into early jazz. Buddy Bolden is considered the first jazz bandleader in New Orleans. Jazz then spread north to Chicago and beyond. Swing became a national craze in the 1930s led by bandleaders like Duke Ellington. Bebop arose in the 1940s as a reaction against swing, led by Charlie Parker and Dizzy Gillespie. Jazz has continued evolving, exploring rock fusion and many other styles over the decades.
Este documento describe el desarrollo de una micro-red social usando el framework Symfony. Incluye instrucciones para instalar Symfony, crear el modelo de datos, generar las clases, importar datos de prueba y configurar las rutas, módulos, plantillas y acciones iniciales. El objetivo es mostrar las características básicas de Symfony como generación de código, navegación de objetos y estructura MVC a través del desarrollo paso a paso de una aplicación simple.
NetBeans es un entorno de desarrollo integrado (IDE) de código abierto que facilita el desarrollo de aplicaciones en Java. Requiere la instalación de Java para funcionar y proporciona herramientas como resaltado de sintaxis, autocompletado de código, compilación y ejecución. También permite diseñar interfaces gráficas arrastrando componentes y agregar plugins que mejoran la funcionalidad.
El documento describe un proyecto de construcción de un sistema de riego por aspersión en el sector Cusi de la comunidad campesina de Arahuara. Se realizará un estudio de impacto ambiental del proyecto que incluye la identificación de posibles problemas ambientales y medidas de mitigación. El estudio analizará los aspectos legales, describirá los componentes ambientales del área y evaluará los posibles impactos durante la construcción y operación. Finalmente, propondrá un plan de manejo ambiental y estimará los costos de las medidas de mitigación.
El documento presenta los estudios básicos y el planteamiento hidráulico para el proyecto de construcción de un sistema de riego por aspersión en el sector Cusi de la comunidad campesina de Arahuara. Los estudios incluyen levantamientos topográficos, características geológicas y mecánica de suelos. El planteamiento hidráulico propone una red de distribución con 42 hidrantes para regar 9.3 hectáreas con un caudal de 7 litros por segundo. Se describen las estructuras de captación
This document summarizes a meetup on authentication with Devise and OmniAuth. Devise is an authentication solution distributed as a Ruby gem that provides modules for password confirmation, recovery, and locking. OmniAuth allows for multi-provider authentication through strategies like Facebook and Twitter, and integrates with Devise using the OmniAuthable module. The meetup goals were to set up basic authentication with Devise, add useful modules, and integrate OmniAuth to allow logging in with a platform of choice. A live coding demo was provided from a GitHub repository.
El documento describe los pasos para realizar mantenimiento preventivo a un equipo. Primero se pasa un pincel seco por el emisor y receptor láser para quitar el polvo. Luego se aplica un chorro de aire comprimido para remover más polvo. Finalmente, se limpian los separadores en la base con algodón o paño humedecido en alcohol para retirar la suciedad.
El documento resume las teorías evolutivas de Darwin y Lamarck. Darwin sostenía que la evolución ocurre a través de la variabilidad entre individuos y la selección natural de las variaciones ventajosas. Lamarck creía que los cambios en el ambiente provocan el uso y desuso de órganos, los cuales se heredan y conducen a la evolución. Mientras que para Darwin la supervivencia de las variaciones aleatorias conduce a la evolución, Lamarck pensaba que el uso y desuso de los órganos impulsados por
La redacción jurídica desempeña un papel fundamental; de su eficacia dependen los resultados de los documentos elaborados para lograr los propósitos legales y/o comerciales. Los textos jurídicos están estrechamente ligados al ejercicio de la argumentación, propio de quienes trabajan en el campo del derecho y la jurisprudencia.
Este seminario-taller está enfocado a conocer y aplicar la estructura argumentativa de los textos jurídicos para su comprensión y redacción, de acuerdo con las herramientas que ofrecen la cohesión, la coherencia y demás elementos gramaticales que componen la lógica textual.
Este documento resume el proceso para la constitución y operación de una sociedad mercantil en Venezuela. Explica los pasos para reservar un nombre, constituir formalmente la sociedad mediante la inscripción de documentos en el Registro Mercantil, realizar asambleas de accionistas, transferir el fondo de comercio, disolver la sociedad y liquidarla. También incluye un modelo de estatutos para una sociedad anónima.
Este documento presenta varios métodos y estrategias para la enseñanza y el aprendizaje centrados en el estudiante, incluido el aprendizaje cooperativo, proyectos, webquests, aprendizaje basado en problemas y portafolios. También discute la importancia de que las escuelas funcionen como organizaciones que aprenden a través de la colaboración entre profesores y el desarrollo de una visión compartida.
Jazz originated in New Orleans in the late 19th century, developing from African rhythms played in Congo Square. Ragtime, with its syncopated rhythms, evolved into early jazz. Buddy Bolden is considered the first jazz bandleader in New Orleans. Jazz then spread north to Chicago and beyond. Swing became a national craze in the 1930s led by bandleaders like Duke Ellington. Bebop arose in the 1940s as a reaction against swing, led by Charlie Parker and Dizzy Gillespie. Jazz has continued evolving, exploring rock fusion and many other styles over the decades.
Este documento describe el desarrollo de una micro-red social usando el framework Symfony. Incluye instrucciones para instalar Symfony, crear el modelo de datos, generar las clases, importar datos de prueba y configurar las rutas, módulos, plantillas y acciones iniciales. El objetivo es mostrar las características básicas de Symfony como generación de código, navegación de objetos y estructura MVC a través del desarrollo paso a paso de una aplicación simple.
NetBeans es un entorno de desarrollo integrado (IDE) de código abierto que facilita el desarrollo de aplicaciones en Java. Requiere la instalación de Java para funcionar y proporciona herramientas como resaltado de sintaxis, autocompletado de código, compilación y ejecución. También permite diseñar interfaces gráficas arrastrando componentes y agregar plugins que mejoran la funcionalidad.
Este capítulo explica cómo crear y editar páginas web (vistas) en HTML y aplicarles estilos en CSS dentro de una aplicación ASP.NET MVC. Se describen conceptos como la creación de vistas, controladores y puntos de entrada para navegar entre páginas. También se recomienda utilizar la librería Bootstrap para dar formato profesional a las interfaces web.
Este documento presenta un tutorial sobre cómo crear y editar interfaces de usuario en aplicaciones web utilizando HTML, CSS y el framework MVC en C#. Explica cómo crear nuevas vistas y carpetas, agregar puntos de entrada en controladores para acceder a las vistas de forma indirecta, y cómo probar los cambios de forma local antes de publicar la aplicación.
Este capítulo explica cómo crear y editar páginas web (vistas) en HTML y aplicarles estilos en CSS dentro de una aplicación ASP.NET MVC. Se describen conceptos como la creación de vistas, controladores y puntos de entrada para navegar entre páginas. También se recomienda utilizar la librería Bootstrap para dar formato profesional a las interfaces web.
Este capítulo explica cómo crear y editar páginas web (vistas) en HTML y aplicarles estilos en CSS dentro de una aplicación ASP.NET MVC. Se describen conceptos como la creación de vistas, controladores y puntos de entrada para acceder a las vistas de forma indirecta. También se recomienda utilizar la librería Bootstrap para darle formato profesional a la interfaz gráfica.
Este documento presenta una guía de 7 días para aprender ASP.NET MVC mediante la creación de laboratorios prácticos. Explica conceptos clave como el uso de controladores y vistas para separar la lógica de presentación, y cómo MVC permite una mejor prueba unitaria y reutilización de código en comparación con el enfoque tradicional de ASP.NET con code-behind. A lo largo de 5 laboratorios, muestra cómo crear una aplicación MVC básica, pasar datos entre controladores y vistas, usar modelos, crear formul
Este documento describe cómo conectar una base de datos de Access y SQL Server a un programa de Visual Basic 6.0, incluyendo los pasos para configurar la cadena de conexión, seleccionar la base de datos, y agregar el código para realizar operaciones básicas como agregar, editar y eliminar registros. También explica cómo crear una aplicación en Visual Studio .NET para conectarse a una base de datos MySQL e incluye un ejemplo básico de código para establecer la conexión.
Este documento proporciona una guía para usar NetBeans para crear proyectos Java. Explica cómo crear un nuevo proyecto Java, agregar paquetes y clases, y usar funciones como generar getters y setters. También cubre cómo implementar interfaces, formatear código y usar control de versiones con Subversion para compartir proyectos entre desarrolladores.
Este documento describe los pasos para conectar una base de datos de Microsoft Access y Microsoft SQL Server a un programa en Visual Basic, así como los pasos para crear una aplicación gráfica que se conecte a una base de datos MySQL. Primero se explica cómo conectar una base de datos de Access mediante un controlador OLE DB y seleccionando los campos correspondientes. Luego se detallan los pasos para conectar a SQL Server a través de SQL Server Management Studio. Finalmente, se indican los pasos para importar la librería MySQL.Data.dll, establecer la conexión a
1) El documento describe los pasos para conectar una base de datos Access y SQL a un programa en Visual Basic, incluyendo configurar el controlador ODBC, establecer la cadena de conexión, y seleccionar los campos. 2) También explica cómo crear una aplicación gráfica en Visual Basic que se conecta a la base de datos SQL, agregando controles, escribiendo código, y programando los botones. 3) Finalmente, detalla cómo conectar una base de datos MySQL a Visual Basic mediante el uso de la librería MySQL Connector .NET.
Este documento proporciona instrucciones para instalar los prerequisitos necesarios para completar ejercicios de aprendizaje de IA en un entorno de laboratorio alojado o en la propia computadora del usuario. Describe los sistemas operativos y software requeridos como Windows 10, .NET Core SDK, Node.js, Python, Git, Visual Studio Code y las extensiones, y el emulador de Bot Framework. Luego, explica cómo crear y probar un bot simple utilizando el SDK de Bot Framework de Microsoft.
Este documento describe la herencia visual de formularios en .NET. Explica que la herencia visual permite derivar un formulario de otro formulario base, heredando sus propiedades y comportamientos. Detalla cómo crear un formulario heredado en el diseñador y cómo los eventos y métodos se ejecutan tanto en el formulario base como en el derivado. Finalmente, presenta un ejemplo práctico de un formulario base que devuelve datos y un formulario heredado que los muestra en una grilla, demostrando la reutilización de código a través de la her
El documento describe los pasos para conectar una base de datos de Microsoft Access, Microsoft SQL Server 2008 y MySQL a Visual Basic 6.0. Explica cómo crear la base de datos, establecer la conexión, y desarrollar la interfaz gráfica para interactuar con los datos. El proceso involucra el uso de controles OLEDB, procedimientos almacenados y librerías como MySql.Data para establecer la conexión y consultar la base de datos.
Este documento describe cómo programar en C# utilizando Visual Studio. Explica cómo descargar e instalar Visual C# Express o Visual Studio, cómo codificar un diagrama de flujo en C# utilizando variables, tipos de datos y operaciones, y cómo crear interfaces visuales con Windows Forms agregando controles y manejando eventos.
Este documento describe cómo programar en C# utilizando Visual Studio. Explica cómo descargar e instalar Visual Studio, los conceptos básicos de programación como variables, tipos de datos y operaciones, y cómo codificar un diagrama de flujo en C#. También cubre cómo crear interfaces gráficas de usuario con Windows Forms para una entrada y salida de datos más amigable para el usuario.
Este documento describe cómo programar en C# utilizando Visual Studio. Explica cómo descargar e instalar Visual C# Express o Visual Studio, cómo codificar un diagrama de flujo en C# usando variables, tipos de datos y operaciones, y cómo crear interfaces visuales usando Windows Forms.
Este documento describe cómo programar en C# utilizando Visual Studio. Explica cómo descargar e instalar Visual Studio, los conceptos básicos de programación como variables, tipos de datos y operaciones, y cómo codificar un diagrama de flujo en C#. También cubre cómo crear interfaces gráficas de usuario con Windows Forms para una entrada y salida de datos más amigable para el usuario.
Introducción al desarrollo Web: Frontend con Angular 6Gabriela Bosetti
El documento presenta una introducción al desarrollo frontend con Angular 6. Los objetivos incluyen comprender el desarrollo frontend con Angular, utilizar un framework MVC como Angular, y ser capaz de desarrollar una Single Page App. Se explican conceptos como TypeScript, Bootstrap, servicios y enrutamiento. Finalmente, se muestra cómo crear y extender un repositorio para migrar la aplicación con servicios backend.
Conexion mysql con java usando netbeansEmerson Garay
El documento describe los pasos para conectar una aplicación Java creada en NetBeans a una base de datos MySQL. Estos incluyen 1) crear una clase ConectorBD para manejar la conexión, 2) agregar la librería JDBC de MySQL, 3) crear la base de datos en MySQL, y 4) diseñar la interfaz gráfica para interactuar con la base de datos.
Similar a Primeros pasos con Backbone js, por Xavier Aznar (20)
Este documento lista los billetes emitidos en España entre 1925 y 1992, durante los regímenes de Alfonso XIII, la Segunda República, Franco y Juan Carlos I, incluyendo los años y valores faciales de cada emisión.
El documento resume los eventos que llevaron al levantamiento del 2 de mayo de 1808 en Madrid contra la ocupación francesa. Tras la abdicación del rey Carlos IV a favor de su hijo Fernando VII y la partida de ambos a Bayona (Francia) bajo presión francesa, el pueblo de Madrid se alzó espontáneamente contra los soldados franceses al saber que los infantes españoles estaban siendo sacados del palacio real. El levantamiento se extendió por toda España y marcó el inicio de la Guerra de Independencia contra Nap
El documento presenta el descubrimiento de restos arqueológicos griegos en Madrid que podrían datar del siglo VII a.C., lo que sugiere que la fundación de la ciudad es anterior a lo estimado. Cronistas del Siglo de Oro como López de Hoyos y Quintana habían mencionado evidencias de la presencia griega, como un dragón labrado en una puerta que podría indicar que los griegos construyeron las murallas. Si se confirman, los hallazgos sacudirían los cimientos de la historia al mostrar que Madrid tiene or
El documento lista diferentes frutas en flor, incluyendo platano, cereza, mandarina, kiwi, frambuesa, manzana, grosella, pera, almendra, pomelo, piña, albaricoque, limón, arandano, naranja, melocotón, ciruela y fresa. También menciona lichi, groseillier, mora y mango.
Sigüenza es una ciudad episcopal en España que mantiene intacta su magia medieval, con lugares como su impresionante catedral románica, la estatua yacente del Doncel Martín Vázquez de Arce, y su castillo que domina la ciudad desde lo alto de la colina. La ciudad también cuenta con bellos edificios como la Casa del Doncel gótica y la Alameda creada para el "solaz de los pobres". Cada rincón de Sigüenza sorprende con su historia y belleza arquitectónica que transportan al visitante
Revista "El estornino de Mozart", marzo 2013Pablo Aguilera
La pandemia de COVID-19 ha tenido un impacto significativo en la economía mundial. Muchos países experimentaron fuertes caídas en el PIB y altas tasas de desempleo en 2020 debido a los bloqueos y restricciones. A medida que se implementan las vacunas, se espera que la actividad económica se recupere en 2021 aunque el panorama sigue siendo incierto.
Revista "El estornino de Mozart", febrero 2013Pablo Aguilera
Contenido:
Efemérides Musicales de Enero
El Concierto de Año Nuevo de la Filarmónica de Viena
Antonio Caldara: Un italiano un la corte vienesa
Vesti la giubba: 8 Visiones de "Pagliacci" y su mítica aria
Constanze
Sir John Falstaff
La opresión Stalinista: Yúdina y Shostakovich
Duelos Sonados: Bach ¿vs? Marchand
Un ejemplo de simetría musical
La melodía del Diablo
Los tweets más interesante
Pasatiempos
#FF
Revista "El estornino de Mozart", enero 2013Pablo Aguilera
Contenido:
Efemérides Musicales de Diciembre
Estornino de Mozart y otras Curiosidades
Leopold Mozart
Wagner y el Holandés Errante: De París a Bayreuth
La Orquesta Enfurecida: El Fenómeno
Duelos Sonados: Mozart vs Clementi
Día Beethoven
El Concierto de 1808
Los Twits más Interesantes
Pasatiempos
#FF
Primeras jornadas madrileñas de novela historicaPablo Aguilera
Las Primeras Jornadas Madrileñas de Novela Histórica tendrán lugar los días 6 y 7 de mayo en Casa del Lector en Madrid. La directora Carolina Molina coordinará presentaciones de novelas históricas y mesas redondas sobre temas como Cervantes y la historia de Madrid. Autores como Toti Martínez de Lezea, Ana Morilla, Luis García Jambrina y otros presentarán sus obras. Los videos y charlas también explorarán aspectos históricos de la ciudad. El evento es gratuito y se espera que sea de interés para lect
25 trucos caseros que te van a hacer la vida más simplePablo Aguilera
¿Como pudiste vivir toda tu vida sin saber esto? Bueno, suena un poco exagerado en realidad, pero no cabe duda que los siguientes trucos te pueden ser útiles para hacer tus tareas cotidianas más fáciles.
Dirk Dzimirsky es un artista autodidacta nacido en 1969 que se dedica a su arte desde 2005. Creó una obra usando solo un lápiz que muchos podrían pensar que está hecha con otros materiales debido a su nivel de detalle y realismo.
El documento no contiene ningún contenido sustancial para resumir. Consiste únicamente en una línea de texto que dice "Plus qu'une simple photo" y luego varias líneas en blanco antes de la palabra "Fin".
La ciudad de Praga se veía hermosa bajo la nieve nocturna del 9 de febrero de 2011. La nieve cubría los tejados y calles de la ciudad checa, dándole un aspecto encantador y tranquilo durante la noche.
La Unión Europea ha propuesto un nuevo paquete de sanciones contra Rusia que incluye un embargo al petróleo ruso. El embargo se aplicaría gradualmente durante seis meses para el petróleo crudo y ocho meses para los productos refinados. El objetivo es aumentar la presión económica sobre Rusia para que ponga fin a su invasión de Ucrania.
El autor aceptó el reto de liderar un proyecto internacional para adaptar una plataforma educativa digital a las necesidades de una gran empresa estadounidense. Tras dos meses de retrasos, el autor se hizo cargo del proyecto. Compartió varias lecciones aprendidas como la importancia de definir bien los requisitos, optimizar la cadena de mando sin perder el control del alcance, y no infravalorar el trabajo del jefe de proyectos. Gestionar proyectos internacionales requiere entender bien al cliente y sus circunstancias organiz
Una lista de rincones que no están en las rutas más usuales, ni entre los destinos más visitados. Algunos son playas, pero no las más accesibles o concurridas, sino rincones escondidos entre acantilados gigantes o bañadas por agua turquesa como una piscina.
Este documento presenta una guía de juegos tradicionales madrileños. Incluye una introducción donde se explica el proyecto de recuperación de juegos y tradiciones populares de las mujeres de Madrid a través de entrevistas. Luego, describe reglas, variantes y anécdotas de más de 30 juegos populares de la región, como Los Alfileres, El Aro, Las Canicas y El Corro, entre otros. El objetivo es preservar esta parte del patrimonio cultural madrileño.
En 1974 la Crónica de la Organización Mundial de la
Salud publicó un importante artículo llamando la atención
sobre la importancia de la deficiencia de yodo como problema
de la salud pública y la necesidad de su eliminación, escrito por
un grupo de académicos expertos en el tema, Prof. JB Stanbury
de la Universidad de Harvard, Prof. AM Ermans del Hospital
Saint Pierre, Bélgica, Prof. BS Hetzel de la Universidad de
Monash, Australia, Prof. EA Pretell de la Universidad Peruana
Cayetano Heredia, Perú, y Prof. A Querido del Hospital
algunos casos de tirotoxicosis y el temor a su extensión con
(18)
distribución amplia de yodo . Recién a partir de 1930 varios
(19)
investigadores, entre los que destaca Boussingault , volvieron
a insistir sobre este tema, aconsejando la yodación de la sal para
su uso terapéutico.
Desórdenes por deficiencia de yodo en el Perú
Universitario, Leiden, Holanda .
(15)
En el momento actual hay suficiente evidencia que
demuestra que el impacto social de los desórdenes por
deficiencia de yodo es muy grande y que su prevención resulta
en una mejor calidad de vida y de la productividad, así como
también de la capacidad de educación de los niños y adultos.
Prevención y tratamiento de los DDI
Los desórdenes por deficiencia de yodo pueden ser
exitosamente prevenidos mediante programas de suplementa-
ción de yodo. A través de la historia se han ensayado varios
medios para tal propósito, pero la estrategia más costo-efectiva
y sostenible es el consumo de sal yodada. Los experimentos de
Marine y col.
(16, 17)
entre 1907 a 1921 probaron que la deficiencia
y la suplementación de yodo eran factores dominantes en la
etiología y el control del bocio endémico. El uso experimental
de la sal yodada para la prevención del bocio endémico se llevó
a cabo en Akron, Ohio, con resultados espectaculares y fue
seguida por la distribución de sal yodada en Estados Unidos,
Suiza y otros lugares. El uso clínico de este método, sin
embargo, fue largamente postergado por la ocurrencia de
La presencia de bocio y cretinismo en el antiguo Perú
antecedió a la llegada de los españoles, según comentarios en
crónicas y relatos de la época de la Conquista y el Virreinato. En
(20)
una revisión publicada por JB Lastres se comenta que Cosme
Bueno (1769), refiriéndose a sus observaciones entre los
habitantes del altiplano, escribió “los más de los que allí habitan
son contrahechos, jibados, tartamudos, de ojos torcidos y con
unos deformes tumores en la garganta, que aquí llaman cotos y
otras semejantes deformidades en el cuerpo y sus corres-
pondientes en el ánimo”. Y es lógico aceptar como cierto este
hecho, dado que la deficiencia de yodo en la Cordillera de los
Andes es un fenómeno ambiental permanente desde sus
orígenes.
Luego de la Independencia hasta los años 1950s, la
persistencia del bocio y el cretinismo endémicos en la sierra y la
selva fue reportada por varios autores, cuyos importantes
(20)
2. Primeros pasos con Backbone.js
Introducción a Backbone.js por Xavi Aznar
Índice
1. Primeros pasos 4
1.1. Requisitos básicos . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2. Enlazando Backbone . . . . . . . . . . . . . . . . . . . . . . 4
2. Modelos 5
2.1. Nuestro primer modelo . . . . . . . . . . . . . . . . . . . . . 5
3. Colecciones 9
4. Vistas 19
5. Plantillas 25
6. Controladores y Eventos 30
7. Eventos y vistas 31
8. Single Page Applications (aplicaciones de una sola página) 33
9. Routers 37
10.Comunicación con el servidor 40
2
3. ÍNDICE ÍNDICE
Comentarios de la adaptación del tutorial al
formato offline
Este eBook es la versión offline del tutorial que se encuentra colgado
en http://bit.ly/1erosPasosBackbone. El tutorial fue pensado como un
bloc de notas donde recoger mis progresos con Backbone. Poco a poco
se fue convirtiendo en un manual con el que iniciarse con uno de los
frameworks más potentes del momento en Javascript.
El texto está creado para ser leído en el navegador, donde los fragmen-
tos de código pueden ejecutarse directamente en la consola de Javas-
cript.
Al realizar la adaptación a un formato offline, como el PDF, esta posi-
bilidad desaparece. Para evitar que el lector se quede sin el feedback
proporcionado por la consola de Javascript, cada fragmento de código
ejecutable en la web se acompaña de una captura de pantalla de la sa-
lida por consola. De esta manera, se consigue una experiencia similar
a la de leer el tutorial en la web. Cuando el código manipula el DOM
-por ejemplo, cuando se trata de vistas-, el texto incluye capturas de la
página web antes y después de la ejecución del código.
En cuanto a los enlaces que aparecen en la página web, en la versión
offline se han complementado con una nota al pie. El enlace sigue sien-
do válido -clickable- en un formato como el PDF, pero se incluye la url
como una nota a pie de página por si quieres imprimir el tutorial como
referencia.
Otro elemento que se queda fuera de la versión offline son los comen-
tarios. A través de los comentarios puedes expresar dudas, quejas,
agradecimientos, sugerencias, puntualizaciones, correcciones... Para
mí son extremadamente importantes, pues me dicen qué hago bien,
qué puedo mejorar... Me hacen saber que hay alguien ahí, al otro lado
a quienes sirve este tutorial... Por tanto, te animo a visitar la página
http://bit.ly/1erosPasosBackbone y hacer oir tu voz.
Esta adaptación la he realizado utilizando LYX (http://www.lyx.org/),
un programa libre y multiplataforma, que permite utilizar la potencia
y flexibilidad del TEX y LATEX a través de un entorno gráfico que facilita
su utilización.
3
4. 1 PRIMEROS PASOS
1. Primeros pasos
1.1. Requisitos básicos
En primer lugar, necesitas un navegador compatible con herramientas
de desarrollador para ver qué está pasando en la consola. Cualquier
navegador moderno servirá, aunque para elaborar este tutorial he uti-
lizado Google Chrome.
Para abrir la consola en Google Chrome, haz click en cualquier lugar
de la página web y elige Inspect Element del menú contextual. Selec-
ciona Console en la parte superior del panel con las herramientas de
desarrollo. También puedes pulsar Crtl + Shift + J (o a través del
menú de Chrome → Tools → Javascript console).
1.2. Enlazando Backbone
Para poder praticar con Backbone, es recomendable que crees una pá-
gina web en la que enlaces los diferentes componentes que requiere
Backbone: jQuery, Underscore, json2 y backbone:
<script type="text/javascript" src="jquery/jquery.min.js"></script>
<script type="text/javascript" src="backbone/json2.min.js"></script>
<script type="text/javascript"
src="backbone/underscore.min.js"></script>
<script type="text/javascript" src="backbone/backbone.min.js"></script>
Aunque Backbone.js sólo tiene como dependencia indispensable a underscore,
para realizar manipulación del DOM y poder gestionar persistencia
RESTful completa, necesitas también json2 y jQuery.
En realidad, json2 sólo es necesario si quieres dar soporte a navegado-
res antiguos que no tengan soporte nativo para JSON, lo que cada día
es menos frecuente.
Para seguir los ejercicios de este tutorial, mantén siempre
abierta la consola de Javascript de tu navegador.
4
5. 2 MODELOS
2. Modelos
2.1. Nuestro primer modelo
En primer lugar, creamos un modelo extendiendo la clase Model de
Backbone. De esta forma creamos nuestra clase personalizada de Mo-
delo. No parece un gran avance, pero en realidad Backbone nos ha pro-
porcionado una serie de métodos para establecer (set) y obtener (get)
propiedades de nuestro modelo, entre muchas otros métodos útiles.
Utilizamos la convención habitual de que los nombres de las
clases empiezan por mayúscula y las instancias, por minús-
culas.
El siguiente código muestra en la consola la creación de un modelo:
Contacto = Backbone.Model.extend();
contacto = new Contacto();
console.log( contacto );
En la consola vemos que se ha creado algo... Utilizamos el método
.toJSON() para convertir el objeto a formato JSON.
5
6. 2.1 Nuestro primer modelo 2 MODELOS
Utilizamos los métodos heredados de Model para establecer y obtener
la propiedad nombre:
Contacto = Backbone.Model.extend(); contacto = new Contacto();
contacto.set( ’nombre’, ’Anthony Machine’ );
console.log( contacto.toJSON() ); console.log( ’El nombre del contacto
es ’ + contacto.get( ’nombre’ ) );
Durante la creación de nuestra instancia del modelo podemos pasar
pares de clave:valor en un solo paso:
Contacto = Backbone.Model.extend();
contacto = new Contacto({
’nombre’: ’Anthony Machine’,
’telefono’: ’555-123-456’
});
console.log( contacto.toJSON() );
console.log( ’El telefono de ’ + contacto.get( ’nombre’ ) + ’ es el ’
+ contacto.get( ’telefono’ ) );
También podemos especificar valores por defecto en la creación de
nuestro modelo personalizado. Los valores por defecto se asignan si no
se especifica un valor para la propiedad (como en el caso del telefono
del segundo contacto):
Contacto = Backbone.Model.extend({
defaults: {
’nombre’: ’John Doe’,
6
7. 2.1 Nuestro primer modelo 2 MODELOS
’telefono’: ’900-123-456’
}
});
contactoDesconocido = new Contacto();
contactoManoli = new Contacto({ ’nombre’: ’Manoli’ });
console.log( contactoDesconocido.toJSON() );
console.log( contactoManoli.toJSON() );
También podemos asignar funciones que actualicen una propiedad de
forma programable. En este caso, lanzamos la función desde la consola
para actualizar el nombre de un contacto creado con los valores por
defecto.
Contacto = Backbone.Model.extend({
defaults: {
’nombre’: ’John Doe’,
’telefono’: ’900-123-456’
},
actualizaNombre: function(){
var nuevoNombre = prompt( ’Introduce el nuevo nombre para el
contacto: ’ );
this.set( {’nombre’: nuevoNombre} );
}
});
contacto = new Contacto();
console.log( contacto.toJSON() );
contacto.actualizaNombre();
console.log( contacto.toJSON() );
En primer lugar, preguntamos al usuario el nombre que quiere asignar
al contacto y después mostramos en la consola cómo hemos actualiza-
do la propiedad nombre del contacto con el valor proporcionado.
7
8. 2.1 Nuestro primer modelo 2 MODELOS
Finalmente, vamos a añadir una función que vigile los cambios que
se producen en la instancia del modelo creado y que nos avise al pro-
ducirse un cambio. Este tipo de funciones se denominan listeners en
inglés.
El listener escucha cambios en el valor de nombre y lanza una función
que registra el cambio en la consola.
Contacto = Backbone.Model.extend({
defaults: {
’nombre’: ’John Doe’
},
actualizaNombre: function( nuevoNombre ){
this.set({ ’nombre’: nuevoNombre });
}
});
// Creación del contacto con el nombre por defecto
contacto = new Contacto();
console.log( contacto.toJSON() );
// Listener
8
9. 3 COLECCIONES
contacto.on( ’change:nombre’, function(){
console.log( ’Nombre del contacto modificado!’ )
} );
// Actualizamos el nombre
contacto.actualizaNombre( ’Miguel Campoviejo’ );
console.log( contacto.toJSON() );
3. Colecciones
Las colecciones (Collection) son conjuntos ordenados de modelos.
Como en el caso de los modelos, para crear una colección extendemos
la clase Collection proporcionada por Backbone.
Como una colección no es más que un conjunto de modelos, al crear la
colección debemos especificar el tipo de modelo que contiene. También
tenemos que especificar una url. Esto es necesario porque al realizar al-
guna operación CRUD, Backbone intenta conectar mediante REST con
la capa de persistencia, es decir, un servidor al otro lador de la URL que
le proporcionamos; allí completará la acción de creación, actualización
o eliminación de los datos de la colección. Si no proporcionamos esta
URL, aparecerán errores en la consola de Javascript.
Creamos la colección y la instanciamos, mostrando el resultado en la
consola usando el método .toJSON():
Contacto = Backbone.Model.extend();
Contactos = Backbone.Collection.extend({
Model: Contacto,
9
10. 3 COLECCIONES
url: "#"
});
contactos = new Contactos();
console.log( contactos.toJSON() );
El resultado es un array vacío. Una colección es un array de objetos,
pero la colección no contiene todavía ningún elemento. Utilizamos el
método .add() para añadir modelos a la colección.
Contacto = Backbone.Model.extend();
Contactos = Backbone.Collection.extend({
Model: Contacto,
url: "#"
});
contactos = new Contactos();
contactos.add({ ’nombre’: ’Anthony Machine’ });
console.log( contactos.toJSON() );
10
11. 3 COLECCIONES
Podemos añadir tantos objetos como queramos, repitiendo la acción
.add():
Contacto = Backbone.Model.extend();
Contactos = Backbone.Collection.extend({
Model: Contacto,
url: "#"
});
contactos = new Contactos();
contactos.add({ ’nombre’: ’Anthony Machine’ });
contactos.add({ ’nombre’: ’Miguel Campoviejo’ });
console.log( contactos.toJSON() );
En vez de añadir los elementos de la colección uno a uno, podemos
añadirlos durante la creación de la instancia de la colección:
Contacto = Backbone.Model.extend();
Contactos = Backbone.Collection.extend({
model: Contacto,
url: "#"
});
contactos = new Contactos([
{ ’nombre’: ’Anthony Machine’ },
11
12. 3 COLECCIONES
{ ’nombre’: ’Miguel Campoviejo’ }
]);
console.log( contactos.toJSON() );
Podemos añadir un contacto a la colección en la posición que deseemos
utilizando at. El siguiente código añade contacto1 en la posición 1
usando at, mientras que el contacto2 se añade al final (posición por
defecto).
Del mismo modo, usamos remove para eliminar un elemento de la co-
lección:
Contacto = Backbone.Model.extend();
contacto1 = new Contacto({ ’nombre’ : ’Mary Sun’ });
contacto2 = new Contacto({ ’nombre’ : ’Federico Mercurio’ });
Contactos = Backbone.Collection.extend({
model: Contacto,
url: "#"
});
contactos = new Contactos([
{ ’nombre’: ’Anthony Machine’ },
{ ’nombre’: ’Miguel Campoviejo’ }
]);
contactos.add( contacto1, {at : 1} );
console.log( contactos.toJSON() );
12
13. 3 COLECCIONES
contactos.add( contacto2 );
console.log( contactos.toJSON() );
// Eliminamos el primer elemento :
primerElemento = contactos.at(0);
contactos.remove( primerElemento );
console.log( contactos.toJSON() );
// Eliminamos un objeto determinado
contactos.remove( contacto2 );
console.log( contactos.toJSON() );
Vamos a verlo con un poco más de detalle;
1. Creamos la colección con dos contactos, y añadimos contacto1
en la posición 1. Después, añadimos contacto2 sin especificar la
posición, de manera que se añade al final de la colección:
13
15. 3 COLECCIONES
3. Finalmente, eliminamos el contacto2 (no hace falta especificar la
posición; Backbone lo busca y lo elimina esté donde esté):
15
16. 3 COLECCIONES
Si queremos actuar sobre todos los elementos de la colección, un mé-
todo como .each() nos resultará útil. En el siguiente ejemplo, recorre-
mos los elementos de la colección y mostramos el nombre en la consola:
Contacto = Backbone.Model.extend();
Contactos = Backbone.Collection.extend({
model : Contacto,
url : ’#’
});
contactos = new Contactos([
{ ’nombre’ : ’Anthony Machine’ },
{ ’nombre’ : ’Miguel Campoviejo’ },
{ ’nombre’ : ’Mary Sun’ }
]);
contactos.each( function( cadaContacto ){
console.log( ’El nombre del contacto es ’ + cadaContacto.get(
’nombre’ ) );
16
17. 3 COLECCIONES
} );
Finalmente, podemos establecer listeners que controlen si se producen
cambios en la colección. En el siguiente ejemplo, vigilamos el evento
add.
Contacto = Backbone.Model.extend();
Contactos = Backbone.Collection.extend({
model: Contacto,
url: ’#’
});
contactos = new Contactos();
//Listener
contactos.on( ’add’, function(){
console.log( "Has cambiado la colección!" );
} );
var nuevoContacto = new Contacto({
’nombre’ : ’Anthony Machine’
});
contactos.add( nuevoContacto );
17
18. 3 COLECCIONES
Un solo listener puede reaccionar a diferentes eventos; para ello sólo
tenemos que incluir los eventos separados por espacios. Modificamos
el código anterior para reaccionar tanto a la adición como a la elimi-
nación de elementos de la colección.
Contacto = Backbone.Model.extend();
Contactos = Backbone.Collection.extend({
model: Contacto,
url: ’#’
});
contactos = new Contactos();
//Listener
contactos.on( ’add remove’, function(){
console.log( "Has cambiado la colección!" );
} );
var nuevoContacto = new Contacto({
’nombre’ : ’Anthony Machine’
});
console.log( ’(Contacto añadido)’ )
contactos.add( nuevoContacto );
console.log( ’(Contacto eliminado)’ );
contactos.remove( nuevoContacto );
18
19. 4 VISTAS
4. Vistas
El proceso para crear una vista (view en inglés) es extendiendo la clase
View proporcionada por Backbone. Creamos la clase sin ningún pa-
rámetro y examinamos qué es lo que nos proporciona una vista en
Backbone.
VistaPrincipal = Backbone.View.extend();
vistaPrincipal = new VistaPrincipal();
console.log( vistaPrincipal );
Al crear una vista obtenemos un objeto con diferentes propiedades. La
propiedad cid es el identificador interno asignado por Backbone a la
vista recién creada. Sin embargo, nos interesan más las propiedades
el y $el (abreviatura de elemento).
La propiedad el es el contenedor de la vista creada. Por defecto, Back-
bone proporciona un div. Puedes pensar en una vista como una caja
en la que mostrar el interfaz de la aplicación web. Todo lo que ten-
gas que dibujar (render en inglés) en el interfaz -botones, formularios,
listas, etc- se mostrará dentro del elemento el de la vista.
Sin embargo, no debes pensar que la vista contiene el HTML de tu
aplicación; contienen la lógica necesaria para presentar al usuario los
datos contenidos en los modelos. La representación de los datos se
realiza, en general, usando algún sistema de plantillas como los mi-
crotemplates de Underscore.js, Mustache, etc... Después de recoger los
19
20. 4 VISTAS
datos y combinarlos con la plantilla, la vista almacena el resultado en
el elemento el.
El siguiente ejemplo muestra como, por defecto, el elemento el de una
vista es un div vacío:
VistaPrincipal = Backbone.View.extend();
vistaPrincipal = new VistaPrincipal();
console.log( vistaPrincipal.el );
Por otro lado, $el es la referencia vía jQuery al objeto contenedor de la
vista (el div, en este caso). Así podemos hacer referencia al elemento y
utilizar los métodos proporcionados por jQuery para manipularlo. Por
ejemplo, $el.show(); sería equivalente a $(’div’).show(); (aunque
probablemente deberías ser más preciso con el selector).
Backbone proporciona un método render para dibujar la vista, aunque
por defecto no hace nada. Backbone permite utilizar cualquier sistema
para mostrar la interfaz en pantalla, así que debemos especificar cómo
se muestra: utilizando concatenación de cadenas, mediante un motor
de plantillas...
Empezamos utilizamos el método .append() de jQuery para añadir un
encabezado en la vista:
VistaPrincipal = Backbone.View.extend({
render: function(){
this.$el.append( ’<h1>Hola Backbone!</h1>’ );
return this;
}
});
20
21. 4 VISTAS
vistaApp = new VistaPrincipal();
vistaApp.render();
console.log( vistaApp.el );
Al llamar a la función render() de forma manual, hemos forzado a
dibujar el encabezado en el div de la vista. Sin embargo, como he-
mos utilizado .append(), si lanzamos .render() múltiples veces, el
contenido se añade también múltiples veces...
VistaPrincipal = Backbone.View.extend({
render: function(){
this.$el.append( ’<h1>Hola Backbone!</h1>’ );
return this;
}
});
vistaApp = new VistaPrincipal();
vistaApp.render();
vistaApp.render();
vistaApp.render();
console.log( vistaApp.el );
21
22. 4 VISTAS
Si esto no es lo que queremos, podemos utilizar .html() para estable-
cer el contenido de la vista, por ejemplo.
VistaPrincipal = Backbone.View.extend({
render: function(){
this.$el.html( ’<h1>Hola Backbone!</h1>’ );
return this;
}
});
vistaApp = new VistaPrincipal();
vistaApp.render();
vistaApp.render();
vistaApp.render();
console.log( vistaApp.el );
Si queremos que la vista se dibuje automáticamente, podemos utilizar
el método initialize. initialize se ejecuta al crear la instancia de
la vista.
VistaPrincipal = Backbone.View.extend({
22
23. 4 VISTAS
initialize: function(){
this.render();
},
render: function(){
this.$el.html( ’<h1>Hola Backbone!</h1>’ );
return this;
}
});
vistaApp = new VistaPrincipal();
console.log( vistaApp.el );
Hasta ahora, toda la acción ha tenido lugar en la consola de Javascript.
El siguiente paso será conseguir mostrar la aplicación web en el nave-
gador. Backbone asigna por defecto al elemento el un div si no se ha
especificado tagName, className o id.
En el siguiente código asignamos una etiqueta H1 mediante tagName al
elemento el. Durante la inicialización de la vista, podemos establecer
variables, etc. En nuestro caso, preguntamos al usuario por su nom-
bre. Después, llamamos a la función render, que se encarga de dibu-
jar la vista. Finalmente, utilizamos jQuery para añadir la vista al DOM,
dentro de un div con id=vista01. Este elemento div id="vista01"
podría ser cualquier elemento previo del DOM, como body, por ejemplo.
Una vez la vista se añade al DOM, aparece en pantalla.
VistaPrincipal = Backbone.View.extend({
tagName : ’h1’,
initialize: function(){
var nombre = prompt ( ’Como te llamas? n (Por defecto =
Backbone)’ );
23
24. 4 VISTAS
nombre = nombre || ’Backbone’;
this.render( nombre );
},
render: function( nombre ){
this.$el.text( ’Hola ’ + nombre +’!’ );
$( ’#vista01’ ).html( this.el );
return this;
}
});
vistaApp = new VistaPrincipal();
Entre el fragmento de código y el siguiente párrafo tenemos div id="vista01"
(vacío):
Cuando ejecutamos el código, se pregunta al usuario:
Se genera la vista y se añade al DOM, justo después del fragmento de
código:
24
25. 5 PLANTILLAS
En Backbone, las vistas incorporan también la funcionalidad asociada
a los elementos de la interfaz gráfica de la aplicación web. Es decir, que
además de la "V" (de Vista), del modelo MVC, también contienen los
controladores (la "C", del modelo MVC).
Al pulsar un botón, añadir un elemento o modificar algún dato en la
aplicación, establecemos listeners para los eventos que se disparen, y
así hacer que la aplicación actualice aquello que sea necesario.
5. Plantillas
Antes de entrar en el tema de la funcionalidad encapsulada en las vis-
tas, creo que es conveniente comentar cómo mostrar en las vistas los
datos contenidos en los modelos.
Backbone nos permite mostrar los datos contenidos en los modelos co-
mo queramos; no nos obliga a hacerlo de una forma determinada. El
método más básico y directo, es simplemente obteniendo los datos des-
de el modelo mediante un modelo.get( ’nombre’ ) e insertándolo en
el DOM.
Aunque podemos concaternar los valores obtenidos de los modelos con
etiquetas HTML y añadirlas directamente al DOM del documento, esta
solución no es la más recomendable.
Underscore.js proporciona un sistema de microplantillas que podemos
utilizar por defecto en nuestras aplicaciones, ya que underscore.js es
una dependencia de Backbone.js.
La función template permite insertar la información contenida en un
modelo, convirtiéndola a formato JSON, en un documento HTML. Para
ello, especificamos el nombre de la "clave" entre < %= ... %>, como se
muestra en el siguiente ejemplo:
25
26. 5 PLANTILLAS
plantilla = _.template( ’Hola < %= nombre %>. Me encanta tu tema < %=
cancion %>!’ );
console.log(
plantilla( {nombre: ’Anthony Machine’, cancion: ’Little black
angels’} )
);
_.template(...) analiza el código que le pasamos en busca de las
etiquetas < %= ... %> que indican dónde debe insertar los valores del
modelo. Si coinciden el nombre de la etiqueta y la clave del modelo,
inserta el valor correspondiente. Si no lo encuentra, se muestra un
error en la consola. Finalmente, devuelve el código de la plantilla con
los valores del modelo ya insertados.
Sin embargo, colocar trozos de código HTML junto con las etiquetas
del motor de plantillas proporcionado por Underscore.js en el código
javascript de la aplicación enturbia el código, haciéndolo menos legible
y claro.
La solución pasa por utilizar la otra dependencia de Backbone, jQuery
y su capacidad para seleccionar y extraer elementos del DOM del do-
cumento HTML.
En el siguiente ejemplo selecciono el contenido del menú de navegación
con el contenido de este documento y lo muestro a través de la consola:
var $menu = $(’#menu ul’).html()
console.log( $menu );
26
27. 5 PLANTILLAS
Como ves, sólo necesitas saber qué quieres seleccionar. Puedes utilizar
el id, el nombre de la class o la etiqueta (entre otras muchas opcio-
nes).
La idea será colocar el HTML de la plantilla que quieres utilizar para
tus datos de la aplicación en el propio documento HTML. Para evitar
que aparezca en el navegador, lo encerramos entre etiquetas script.
Aunque el navegador no lo muestre, intentará interpretarlo como si
fuera javascript (por defecto). Pero tampoco es éso lo que queremos, así
que especificamos type="text/template; el navegador no sabrá como
interpretarlo y por tanto, lo ignorará. En realidad podemos clasificarlo
como text/LoQueSea, pero por convención se utiliza el tipo template
(plantilla, en inglés).
Finalmente, para poder acceder al fragmento de código que contiene la
plantilla con facilidad, lo designamos con un id único.
El fragmento de código a continuación muestra cómo podría ser una
plantilla para mostrar la información del siguiente ejemplo:
<script type="text/template" id="plantilla-vistapersonaje">
<h1> < %= nombre %> </h1>
<p>
<a href="< %= wikipediaurl %>" class="mas-info">
Información en la wikipedia sobre < %= nombre %>
</a>
</p>
</script>
27
28. 5 PLANTILLAS
Ahora, el código de la vista para el contacto será:
Personaje = Backbone.Model.extend();
VistaPersonaje = Backbone.View.extend({
el: ’#vista02’,
plantilla: _.template( $(’#plantilla-vistapersonaje’).html() ),
initialize: function( modelo ){
this.$el.html( this.plantilla ( modelo.toJSON() ));
},
render: function(){
$(’#vista02’).html( this.$el );
return this;
}
});
personaje = new Personaje({
’nombre’: ’Antonio Machín’,
’url’: ’http://es . wikipedia . org/wiki/Antonio_Mach %C3%ADn’
})
vistaPersonaje = new VistaPersonaje( personaje );
Antes de ejecutar el código:
Y después, cuando hemos generado la vista a partir de la información
contenida en el modelo:
De esta forma conseguimos separar el código HTML de la plantilla de
la funcionalidad relacionada con la vista. No hace falta preocuparse
28
29. 5 PLANTILLAS
sobre cómo se van a mostrar los datos de la aplicación, de los estilos
o etiquetas en los que se encuentran. Sólo tienes que saber que en la
plantilla habrá un hueco con la clave del dato que se insertará en esa
posición (y dejar el diseño a un especialista, por ejemplo).
Si se modifica la plantilla...
<script type="text/template" id="plantilla-vistapersonaje2">
<ul>
<li> <a href="< %= url %>"> < %= nombre %> </a></li>
<li> <a href="< %= url %>"> < %= nombre %> </a></li>
<li> <a href="< %= url %>"> < %= nombre %> </a></li>
<li> <a href="< %= url %>"> < %= nombre %> </a></li>
</ul>
</script>
...el código no cambia:
Personaje = Backbone.Model.extend();
VistaPersonaje = Backbone.View.extend({
el: ’#vista02’,
plantilla: _.template( $(’#plantilla-vistapersonaje2’).html() ),
initialize: function( modelo ){
this.$el.html( this.plantilla ( modelo.toJSON() ));
},
render: function(){
$(’#vista02’).html( this.$el );
return this;
}
});
personaje = new Personaje({
’nombre’: ’Antonio Machín’,
’url’: ’http://es . wikipedia . org/wiki/Antonio_Mach %C3%ADn’
})
vistaPersonaje = new VistaPersonaje( personaje );
sin embargo, la salida sí que es diferente, pues la plantilla que hemos
utilizado es diferente:
29
30. 6 CONTROLADORES Y EVENTOS
Hasta ahora, sabemos que la vista tiene una propiedad el, que contie-
ne una referencia a un elemento del DOM del documento. Mediante la
función _.template(...) de Underscore.js, extraemos el HTML de la
plantilla y lo combinamos con los datos almacenados en el modelo. Y
mediante render(...) lo dibujamos en el documento HTML.
Sin embargo, antes de empezar este apartado sobre plantillas decía que
las vistas también contienen funcionalidad asociada a los elementos
visuales de la aplicación. Vamos con esta funcionalidad...
6. Controladores y Eventos
En el modelo MVC una aplicación se encuentra separada en tres tipos
de componentes. En Backbone.js los controladores se incluyen en las
vistas, con lo que no podríamos hablar estrictamente de un modelo
MVC .
En realidad, en las primeras versiones de Backbone.js sí que
había una clase controller, solo que en la versión 0.5.0 se
renombró a router. Más adelante hablo de los routers.
El controlador no es más que una función que se encarga de reaccionar
a las acciones que realiza el usuario sobre los componentes visuales de
la aplicación y actualiza los datos del modelo en consecuencia.
Para poder reaccionar a las acciones del usuario necesitamos un siste-
ma que gestione los eventos que éste produce (hacer click en un botón,
enviar un formulario, etc).
30
31. 7 EVENTOS Y VISTAS
Backbone.js proporciona un sistema de gestión de eventos que permite
asociar listeners a los selectores incluidos en el elemento el (o directa-
mente a el si no se proporciona ningún selector). Los eventos se recogen
en forma de hash de la forma "evento selector" : "callback".
El siguiente ejemplo muestra lo que podría ser un hash de eventos para
una aplicación de agenda de contactos:
events : {
’dblclick label’ : ’muestraEditaContacto’,
’blur .editar’ : ’cierraEditaContacto’,
’click .elimina’ : ’eliminaContacto’
}
muestraEditaContacto, cierraEditaContacto y eliminaContacto
son funciones que deben estar definidas en el mismo ámbito de la vista.
En realidad, Backbone proporciona un sistema de eventos muy po-
tente, que va más allá de las vistas y que permite gestionar eventos
de modelos, colecciones, routers, el historial y de los objetos y eventos
propios que definas para tu aplicación.
Antes de centrarme en el uso de eventos relacionados con las vistas,
comentaré brevemente los Eventos en Backbone.js.
Backbone.Events puede utilizarse para asociar eventos personaliza-
dos a cualquier objeto que definamos.
7. Eventos y vistas
Una de las ventajas de Backbone.js es que los diferentes componentes
que integran la aplicación -modelos, vistas y el DOM- se comunican
31
32. 7 EVENTOS Y VISTAS
entre sí. Esta comunicación es bidireccional, tanto si se actualiza la
información contenida en el modelo como si se genera un evento en la
vista que afecta al modelo.
En Backbone.js la Vista hace de concentrador de todo lo que sucede
en nuestra aplicación. Ya hemos visto antes que un cambio en el mo-
delo permitía, a través de un listener, reaccionar ante un cambio en
el modelo. En general, cuando cambia la información contenida en los
modelos de nuestra aplicación querremos actualizar la vista, mostran-
do la información actualizada.
Del mismo modo, cuando se produce un evento en la vista, actualiza-
mos el modelo o la colección correspondiente.
32
33. 8 SINGLE PAGE APPLICATIONS (APLICACIONES DE UNA SOLA
PÁGINA)
8. Single Page Applications (aplicaciones de
una sola página)
Hasta ahora hemos estado practicando directamente en la línea de co-
mando, creando modelos, colecciones y vistas. También hemos visto
que una de las ventajas de Backbone es que todos los elementos se
comunican entre sí, a través de eventos asociados a los diferentes mo-
delos o vistas de nuestra aplicación web. De hecho, Backbone.js pro-
porciona toda la infraestructura necesaria para crear lo que se denomi-
nan single page applications, es decir, una aplicación web de una sola
página. Esta página contiene el HTML, las CSS y el código javascript
necesario para interaccionar con los datos obtenidos desde el servidor
y mostrarlos a través de las vistas.
Imagina una aplicación de agenda como la que he dibujado más abajo.
En la vista principal se muestra la lista completa de contactos (sin
filtrar). Junto a cada uno de los contactos, tenemos un botón para
editar la información del contacto. Al pulsarlo, se muestra una nueva
página con la información del contacto.
33
34. 8 SINGLE PAGE APPLICATIONS (APLICACIONES DE UNA SOLA
PÁGINA)
En una aplicación tradicional, el cliente solicita la página web al ser-
vidor, donde se procesa la petición. Inicialmente, se devuelve una lista
de todos los contactos. Cuando el cliente pulsa sobre un contacto para
editar los datos relacionados, se realiza la petición al servidor, que ob-
tiene los datos relativos al contacto seleccionado, se combinan con la
plantilla adecuada y se devuelven al cliente. Como todo el procesamien-
to de los datos se realiza en el servidor, cada vez que hay que tratar con
los datos, hay que contactar de nuevo con el servidor.
34
35. 8 SINGLE PAGE APPLICATIONS (APLICACIONES DE UNA SOLA
PÁGINA)
En una aplicación con Backbone.js, los datos se procesan en el cliente
(el navegador): al solicitar la página, el servidor devuelve el documen-
to HTML que contiene todas las plantillas que necesitan las vistas de
la aplicación junto con los datos. Cuando el cliente interacciona con
la aplicación, no es necesario volver a contactar con el servidor, sino
simplemente cambiar la vista, filtrando los datos adecuados:
35
36. 8 SINGLE PAGE APPLICATIONS (APLICACIONES DE UNA SOLA
PÁGINA)
El problema es que todas las vistas de la aplicación comparten la URL,
por lo que hay que proporcionar algún método para que el usuario
pueda acceder a una determinada funcionalidad de la aplicación web
(por ejemplo, a la visualización de un contacto determinado). Usando
REST esta URL será de la forma http://agenda.me/contacto/1, por
ejemplo. El problema es que esta URL no existe. Sin embargo, podemos
crear un enlace similar mediante el uso de una hash url; utilizando el
signo de la almohadilla # indicamos al navegador que el enlace apunta
a un fragmento de la página web, por lo que conseguimos URLs váli-
das como http://agenda.me/#contacto/1. Otro problema relaciona-
do con estas aplicaciones de una sóla página es que todos los enlaces
con hash urls no eran indexados por los buscadores. Pero desde hace
un tiempo los buscadores aceptan una especificación que permite inde-
xar todas estas URLs virtuales, por llamarlas de algún modo. Si quieres
que los buscadores indexen los enlaces de tu aplicación web, utiliza la
combinación #!. Puedes completar información al respecto échandole
un vistazo a https://developers.google.com/webmasters/ajax-crawling/
.
36
37. 9 ROUTERS
9. Routers
Para solucionar el problema de las URLs relacionados con la single
page applications Backbone.js proporciona los router.
Hasta la llegada de la API History había que utilizar las hash urls (p.ej.
agenda.me/#edit) para proporcionar al usuario enlaces que pudieran
ser enlazables, bookmarkables, etc.
El problema es que para que un navegador pase de la URL agenda.me/contacto/1
a agenda.me/contacto/2, se requiere que se haga una petición al ser-
vidor y que este devuelva el contenido de la URL agenda.me/contacto/2.
Este proceso, llamado navegación actualiza la historia del navegador.
Así podemos pulsar los botones atrás/adelante del navegador para
avanzar/retroceder por el historial de navegación.
Con las urls fragmentadas, cuando el navegador pasa de agenda.me/#contacto/1
a agenda.me/#contacto/2 no se produce un cambio de página, sino
un cambio en la parte que se visualiza de una misma página. No hay
llamada al servidor y por tanto, no hay actualización de la historia de
navegación.
Con la llegada de este API, las aplicaciones web pueden manipular la
historia del navegador, de manera que un cambio de una URL a otra
-aunque sea una hash url- sí se interpreta como una navegación entre
páginas y, por tanto, queda registrado en la historia del navegador. De
esta forma las urls fragmentadas pasan a comportarse como urls de
verdad y pueden utilizarse para enlazar, para añadir a favoritos, para
compartir por mail, etc.
Backbone.js proporciona la clase Backbone.router para gestionar es-
tos cambios de URLs en las aplicaciones del lado del cliente y asociarlas
a acciones y eventos. Además, para los navegadores que no soportan el
API de la historia de navegación el router se degrada de forma trans-
parente a la versión hash de la URL.
La creación de un router se realiza mediante la extensión de Backbone.Router,
como es habitual en Backbone.js.
Dentro de nuestra instancia de router definimos el conjunto de urls
internas -llamadas rutas- de la aplicación y las funciones a las que
37
38. 9 ROUTERS
deben llamar cuando se navegue a una url determinada. En estas URLs
podemos incluir una o varias partes variables, que será interpretadas
como parámetros:
var Agenda = Backbone.Router.extend({
routes : {
"ayuda" : "ayuda",
"busca/:consulta" : "busca"
},
ayuda: function(){
...
},
busca: function( consulta ){
...
}
});
En el ejemplo anterior he definido dos rutas; la primera corresponde a
miagenda.#ayuda corresponde a una ruta básica. La aplicación mapea
la ruta agenda.me/#ayuda con la función ayuda.
En el segundo caso hemos definido la ruta añadiendo :consulta; de
esta manera indicamos que este fragmento de la URL es un paráme-
tro y que debe ser asignado a la variable consulta, que pasamos a la
función correspondiente. Es decir, agenda.me/#busca/antonio resul-
ta en busca( "antonio" ); en la aplicación.
Con estos dos tipos de rutas tienes las opciones más comunes para de-
finir rutas. De todas formas, consulta la documentación en Backbone.js/#Router
para descubrir otras formas de pasar parámetros desde las URLs a las
funciones de tu aplicación.
Una vez creadas y configuradas las rutas de la aplicación web, indica-
mos a Backbone.js que monitorice los eventos de cambio de hash urls
y ¡listo!
Backbone.history.start();
38
39. 9 ROUTERS
Podemos pasar opciones a start, por ejemplo, si queremos usar pushState
o si la página web no es servida directamente desde la raíz del do-
minio... Como siempre, es recomendable que mires la documentación
oficial completar información sobre History.
Una vez arrancada la monitorización de cambios en la url, Backbone.js
se encarga de actualizar el historial del navegador de forma automática.
Si desde la aplicación web queremos forzar la navegación de un punto
a otro de la aplicación, utilizamos el método navigate de router:
...
this.navigate( "pagina/" + numPagina );
...
Si la url a la que estamos navegando forma parte de las rutas definidas,
es probable que queramos que se dispare la función asociada definida
en la ruta; para ello, pasamos {trigger:true} a navigate:
routes: {
"ayuda/faq" : "faqMsg"
},
faqMsg: function(){
alert( ’Gracias por consultar las preguntas frecuentes’ );
}
...
agenda.navigate( "ayuda/faq", {trigger: true} );
En resumen, definimos unas rutas en Backbone.Router, que mapea-
mos a funciones relacionadas con las acciones que lleva a cabo la apli-
cación. Con Backbone.history.start() la aplicación reacciona au-
tomáticamente a los cambios de url, actualizando el historial de nave-
gación. Si desde la aplicación queremos simular una de estas navega-
ciones, usamos el método navigate.
39
40. 10 COMUNICACIÓN CON EL SERVIDOR
10. Comunicación con el servidor
Una de las ventajas de Backbone es que reduce las peticiones necesa-
rias al servidor. En su lugar, Backbone utiliza las vistas para mostrar
únicamente la información necesaria en la vista actual.
Los datos de una aplicación web se almacenan en lo que se llama la ca-
pa de persistencia, que normalmente es una base de datos. Esta base
de datos se encuentra en el servidor, por lo que antes o después, desde
la aplicación web hay que establecer comunicación con el servidor para
actualizar datos. Backbone proporciona toda la infraestructura nece-
saria para realizar la comunicación entre el navegador y el servidor de
forma sencilla.
Primero comentaré lo que pasa en general, usando únicamente REST.
Después, veremos cómo Backbone ejecuta estos comandos a través del
módulo Backbone.sync. sync es un mecanismo de bajo nivel, dentro
del framework; en el día a día del desarrollo de la aplicación web uti-
lizaremos otros métodos propios de modelos, colecciones y vistas, que
son los que internamente utilizan sync y que comentaré al final de esta
sección.
Siguiendo con el ejemplo de la agenda, durante la primera conexión
Backbone descarga la información de todos los contactos. Después, si
el usuario consulta el contacto 1, muestra una vista de detalle con los
datos filtrados para ése único usuario, sin necesidad de ponerse en
contacto con el servidor de nuevo. A continuación vamos a entrar en
detalle sobre cómo se comunica Backbone para obtener y actualizar la
información.
En la documentación oficial de Backbone dice que proporciona un in-
terfaz REST completo a través de JSON (traducción libre de : [...] and
connects it all to your existing API over a RESTful JSON interface). ¿Qué
quiere decir ésto?. En la página en castellano de la Wikipedia encon-
tramos la definición del significado de REST, de donde destaca:
protocolo cliente/servidor sin estado: cada mensaje intercambia-
do contiene toda la información necesaria para comprender la pe-
tición.
40
41. 10 COMUNICACIÓN CON EL SERVIDOR
un conjunto de operaciones bien definidas: aunque incluye otras,
en la práctica se utilizan sólo cuatro GET, POST, PUT, DELETE.
sintaxis universal que permite identificar los recursos a través de
su URI.
Con estas ideas en mente, ahora volvemos a la aplicación de la agenda.
Cuando el usuario accede a http://agenda.me/, es decir a la raíz
de nuestra aplicación /, seguramente nos interese definir una route
hacia /contactos/. Como no especificamos ningún id de contacto,
si lo hemos programado así, nuestro servidor nos devolverá todos los
contactos almacenados en la base de datos (mediante GET).
Cuando el usuario introduce un nuevo contacto, enviamos la informa-
ción al servidor mediante POST; el servidor se encarga de asignar el
siguiente id libre en el equivalente en nuestra base de datos de la lista
de /contactos.
Si el usuario quiere acceder a un contacto concreto, como el que tiene el
id=5, en este caso el identificador (URI del recurso) será: /contactos/5,
de nuevo, usando GET.
Mediante DELETE indicamos que vamos a borrar un contacto. Para ello
debemos aportar el id del contacto a borrar; por ejemplo, como antes
/contactos/5.
Finalmente, usamos PUT para actualizar la información de un contacto
(o crear uno nuevo). Como es lógico, aportamos el id del contacto que
queremos acutalizar junto con la información actualizada.
Backbone proporciona toda esta funcionalidad a través de Backbone.sync.
sync toma tres parámetros: method, model y options (este último es
opcional). El method es uno de los cuatro verbos de REST: GET, POST,
PUT, DELETE. El segundo, model es el modelo a guardar en el servidor
(o la colección que vamos a leer); Backbone interpreta qué tiene que
hacer con los datos que le pasamos.
Enlazando con el ejemplo anterior de la agenda, por defecto sync sería
algo así:
crear nuevo contacto : POST →/contactos
41
42. 10 COMUNICACIÓN CON EL SERVIDOR
leer (contacto o colección): GET → /contactos[/id] Si no se pro-
porciona un id, es que queremos leer toda la colección.
actualiza un contacto : PUT → /contactos/id
borrar contacto : DELETE → /contactos/id
Aunque Backbone.sync usa jQuery.ajax(), en realidad podemos sus-
tituirlo por cualquier otro método que nos interese, en función de nues-
tras necesidades. Un ejemplo de ello es la aplicación localtodos, que
usa Backbone.localStorage. localStorage funciona como un plu-
gin que usa el local storage (almacenamiento local) de HTML5 en vez de
un servidor de bases de datos como capa de almacenamiento.
Como he comentado al principio de esta sección, sync es un meca-
nismo interno de Backbone; al desarrollar la aplicación web rara vez
tendremos que llamar a sync de manera manual.
De nuevo volvemos al ejemplo de la agenda. La primera vez que el
usuario accede a la aplicación web crearemos una colección Contactos
donde almacenar localmente la información obtenida del servidor. En
la definición de la colección habremos incluido la propiedad url, que
indica a Backbone dónde buscar y almacenar los datos contenidos en
la colección. En la sección sobre Colecciones de este tutorial verás que
utilicé url: ’#’ para evitar que Backbone se intentara comunicar con
una url externa a la página.
Ahora, suponiendo que ya tenemos el servidor configurado, nuestra
colección incluiría:
Contactos = Backbone.Collection.extend({
Model: Contacto,
url: "/contactos/"
});
Así la colección sabe dónde están almacenados los datos con los que
se relaciona. Por tanto, en la función de inicialización de la colección
podemos incluir:
42
43. 10 COMUNICACIÓN CON EL SERVIDOR
initialize: function(){
...
Contactos.fetch();
...
};
fetch obtiene los datos almacenados en la url de la colección en el
servidor. En nuestro ejemplo de la agenda, obtendría todos los datos
almacenados en la base de datos, pasándolos a una vista y mostrándo-
los al usuario al visitar la página por primera vez. Incluso si llamamos
a fetch en respuesta a algún evento que se produce en la aplicación,
Backbone utiliza set para fusionar los datos locales con los obteni-
dos del servidor de forma inteligente (a no ser que utilicemos {reset:
true}). En las opciones de fetch podemos espeficificar funciones de
callback para los eventos success y error de comunicación con el ser-
vidor, actuando en consecuencia. A estas funciones Backbone les pasa
automáticamente collection, response y options como argumen-
tos. De hecho, fetch delega su ejecución a Backbone.sync de forma
transparente (que a su vez utiliza jQuery.ajax() para realizar la co-
municación con el servidor).
fetch hace que se disparen los eventos add para cada modelo añadido
y change para cada modelo cambiado. Así, si hemos especificado que
ocurran cosas cuando cambien los modelos -por ejemplo, actualizar
una vista- se ejecutará el código adecuado y todo funcionará sin que
tengamos que preocuparnos por ello.
fetch puede llamarse tanto para modelos como para colecciones. Si
url no está definido para el modelo, utiliza url de la colección asocia-
da. El único requerimiento para fetch es que el servidor devuelva un
array de modelos en formato JSON.
Volviendo la vista atrás un momento, tenemos que, lo que anteriormen-
te habíamos comentado:
leer (contacto o colección): GET → /contactos[/id] Si no se pro-
porciona un id, es que queremos leer toda la colección.
sería, mediante fetch:
43
44. 10 COMUNICACIÓN CON EL SERVIDOR
leer (contacto o colección):
Contactos.fetch()
(toda la colección) o
Contacto.fetch()
(para obtener un contacto en concreto).
Al obtener el contacto no tenemos que especificar el id del modelo, ya
que internamente Backbone sabe cuál es el id asociado a cada modelo
de una colección, y no hace falta que lo especifiquemos nosotros.
Para el resto de operaciones de creación, actualización o eliminación
de modelos, tal y como hemos hecho con fetch utilizamos funciones
específicas en vez de utilizar Backbone.sync a pelo.
Backbone proporciona el método save para guardar un nuevo modelo
en la base de datos o para actualizar uno existente.
Contacto = Backbone.Model.extend();
var contacto = new Contacto({
nombre: ’Anthony Machine’,
telefono: ’+34931234567’
});
contacto.save(); // Lo guarda en el servidor
El siguiente trozo de código (adaptado de la página de Backbone) mues-
tra una función sync modificada, que muestra un alert() en vez de
comunicarse con el servidor. Al ejecutar el código por primera vez, save
envía el modelo completo, ya que no existe inicialmente. En la segun-
da llamada a save, especificamos sólo la parte de la información del
contacto actualizada; Backbone te facilita el trabajo y no es necesario
utilizar funciones diferentes para crear y actualizar ni es necesario es-
cribir código para comprobar si un registro existe antes de modificarlo
y cosas por el estilo...
44
45. 10 COMUNICACIÓN CON EL SERVIDOR
Backbone.sync = function(method, model) {
alert(method + ": " + JSON.stringify(model));
model.id = 1;
};
var contacto = new Backbone.Model({
nombre: "Anthony Machine",
telefono: "+34931234567"
});
// Primera llamada : crea el contacto
contacto.save();
// Segunda llamada : actualiza el contacto ( que ya existe )
contacto.save({nombre: "Federico Mercurio"});
En la primera llamada:
Y en la segunda:
45
46. 10 COMUNICACIÓN CON EL SERVIDOR
Para evitar enviar el modelo completo, podemos utilizar el parámetro
{patch: true} que envía sólo los atributos modificados al servidor,
optimizando las comunicaciones. Backbone utiliza isNew() para de-
terminar si el modelo no existe -con lo que envía un HTTP POST, para
crearlo- o si estamos haciendo una actualización, con lo que envía HTTP
PUT.
Finalmente, para eliminar un modelo del servidor, usaremos destroy(),
lo que genera una petición HTTP DELETE.
var contacto = new Backbone.Model({
nombre: "Justino Biever",
telefono: "+34666234567"
});
// Nos deshacemos del contacto
contacto.destroy();
Obviamente, estas acciones están asociadas a los modelos que vamos
a modificar. Si queremos llevar a cabo estas acciones (por ejemplo, eli-
minar) para toda una colección, utilizamos el método de underscore.js
_.each() para actuar sobre cada modelo de la colección.
46
47. 10 COMUNICACIÓN CON EL SERVIDOR
En esta sección he intentado clarificar un poco cómo gestiona Back-
bone la comunicación del servidor. Backbone proporciona métodos es-
pecíficos para modelos y/o colecciones que permiten realizar las ope-
raciones básicas de manipulación de modelos y colecciones: fetch(),
save(), destroy(), equivalentes a las operaciones CRUD (Crear, leer
(read), actualizar (update) y destruir). Backbone es suficientemente
inteligente como para distinguir cuándo se trata de crear o actua-
lizar un modelo. Internamente estos métodos específicos delegan en
Backbone.sync. Por defecto, sync usa la función .ajax() de jQuery
(o de Zepto) para comunicarse con el servidor, aunque podemos cam-
biarlo fácilmente.
Además de proporcionar la infraestructura necesaria para realizar la
comunicación con el servidor, Backbone también se encarga de dispa-
rar eventos que permiten a otras partes de nuestra aplicación reaccio-
nar ante los cambios que se produzcan en los modelos, independiente-
mente de su origen.
47