Webapps PDF
Webapps PDF
of Contents
1. Introduction 1.1
2. Entorno de trabajo 1.2
1. Software 1.2.1
2. Configuracin de Sublime Text 1.2.2
3.
4. Multimedia 2.1
1. Imagen 2.1.1
2. Video 2.1.2
3. Audio 2.1.3
4. Qu funciona en la web 2.1.4
5.
6. La Web actual 3.1
1. La Web actual 3.1.1
2. Proyecto Web bsica 3.1.2
3. Tiempo de carga 3.1.3
7.
8. CSS avanzado 4.1
1. Lenguajes de preprocesado: Sass 4.1.1
2. Uso de Bootstrap 4.1.2
9.
10. JavaScript 5.1
1. Caractersticas generales 5.1.1
2. linters 5.1.2
3. jQuery 5.1.3
1. Efectos en jQuery 5.1.3.1
2. html y jQuery 5.1.3.2
3. Eventos 5.1.3.3
4. Ajax 5.1.3.4
5. Adios jQuery? 5.1.3.5
11.
12. Node.js 6.1
1. Introduccin a Node.js 6.1.1
2. Crear una librera en node.js 6.1.2
3. Arquitectura de una API REST 6.1.3
4. Creacin de una API con node.js 6.1.4
13.
14. SPA 7.1
1. Arquitectura de un SPA 7.1.1
2. PhoneGap 7.1.2
15.
16. Web Components 8.1
1. Entorno de desarrollo mediante Webpack 8.1.1
2. Caractersticas de ES2015 8.1.2
3. Evolucin del CSS 8.1.3
4. Reactjs 8.1.4
5. Real Time 8.1.5
17.
18. Proyectos solucionados 9.1
1. Proyecto Web bsica 9.1.1
1
2. Web con bootstrap y gulp 9.1.2
3. React.js con material-ui 9.1.3
2
Introduction
Introduction
Introduccin
Objetivos del curso
Configurar entornos reales de trabajo para desarrollo web
Editor de cdigo
Control de versiones
Automatizacin de tareas
Pginas adaptables
Criterio Mobile First
Frameworks de CSS: Bootstrap y Material Design
Frameworks de JavaScript: React.js
MEAN stack
Real time
Aplicaciones hbridas para mviles
Web Components
Conocimientos previos
html, css y js bsico
Puedes seguir este tutorial para html y css bsico
Empezaremos con un ejercicio prctico:
Nos familiarizamos con Sublime Text
Practicamos con Emmet
Repasamos Chrome Developer Tools
Repasamos etiquetas html5 y css
3
Introduction
Bases de datos
Lenguaje de marcas
Programacin
Entornos de desarrollo
Cmo trabajar
4
Introduction
Roles
Quin es el profesor?
Persona con conocimientos lmitados
Tiempo de respuesta: horas? das?
Buen orientador
Quin es stackoverflow?
Multitud de personas con mltiples conocimientos (ver tags)
Tiempo de respuesta: minutos?
La mejor herramienta junto con GitHub para ir haciendo curriculum
Otras ideas
Servidor en la nube
So You Start con Vesta
Primer portfolio del alumno
Entorno real
Virtualiza con Docker
Ms rpido
Se puede montar un servidor de imgenes Docker en el propio centro
Uso de gestores de contenidos (Wordpress, Joomla, Magento, Prestashop)...
Documentacin
Generada con Gitbook
cd curso-webapps
gitbook install
npm install -g gitbook-cli
npm install
npm run slides
npm run pdf
npm run epub
npm run mobi
6
Entorno de trabajo
Entorno de trabajo
Entorno de trabajo
Los objetivos de este captulo son los siguientes:
Tener una lista de software necesario y su procedimiento de instalacin, de modo que se pueda
replicar de forma rpida.
Tener anotados todos los ajustes, configuraciones y plugins que nos van a hacer falta en los
distintos programas (especialmente en Sublime Text) que utilizaremos a lo largo de todo el
curso.
7
Software
Software
Instalacin y configuracin del software
nvm
Instalaremos y utilizaremos node va nvm (node virtual manager)
nvm ls
node
La otra opcin sera instalar directamente node:
npm -v
node -v
git
Instalacin de git:
8
Software
Configuracin de git
Configuracin de GitHub
ssh-keygen
Instalacin de zsh
Algunos prefieren fish
Instalo oh-my-zsh
9
Software
La eleccin de un IDE o un editor de cdigo no es trivial y la configuracin del mismo para explotar
todas sus posibilidades tampoco.
Instalacin de MongoDB
Instalaremos primero mongodb:
Y para entrar a su consola, mediante mongo, o mediante algn gui como por ejemplo
Robomongo, que tambin podemos instalar desde su web.
ubuntu-make
Instalacin de umake:
10
Software
umake -h
# por ejemplo en IDES
umake ide -h
Variables de Shell
export ANDROID_HOME='/home/usuario/Android/Sdk'
path+=('/home/usuario/Android/Sdk/tools' '/home/usuario/Android/Sdk/platfo
Aado tambin el repositorio de los binarios de npm (lo utiliza Sublime Text y al usar zsh hay
que drselo). Fichero $HOME/.zshenv:
path+=('/home/usuario/.nvm/versions/node/v5.0.0/bin/')
Test de funcionamiento
11
Configuracin de Sublime Text
WebStorm
NetBeans, Eclipse, Android Studio
Visual Studio Code?
Terminal
VCS (Version Control System)
Task Runner (Grunt, gulp...)
Debug, testing...
12
Configuracin de Sublime Text
Mocha Snippets:
desc<tab>
befr<tab>
aftr<tab>
suite<tab>
test<tab>
Aadiremos snippets de React a Sublime para poder trabajar con React ms rpido
Babel como Syntax Highlighter. Habr que configurar los ficheros con extensin js para que lo
usen por defecto, ver https://packagecontrol.io/packages/Babel
Configuracin tabulaciones
Necesario para lenguajes como Python
En nuestro caso por criterio de formato de cdigo
Fichero Preferences->Settings - Users:
13
Configuracin de Sublime Text
{
"tab_size": 2,
"translate_tabs_to_spaces": true
}
14
Multimedia
Multimedia
15
Imagen
Imagen
Imgenes
Introduccin
Las imgenes un elemento clave para una web bien diseada
Las pginas web atractivas se encuentran, no se hacen:
Bsqueda de imgenes
Bsqueda de iconos
Bsqueda de patterns
Bancos de fotografas
http://www.gettyimages.es/
http://www.shutterstock.com/
http://www.istockphoto.com/
http://www.fotolia.com
http://www.bigstockphoto.com/
http://www.sxc.hu/ (gratuito)
Caso prctico
La eleccin de imgenes puede llevar mucho tiempo y es vital para el aspecto final de nuestra
web.
Ejemplos de imgenes para webs de accidentes de trfico:
http://abogadoaccidentetrafico.es/
http://www.marianosanchez.com/
http://www.solernaharro.com/
Qu tipo de imgenes utilizaras tu?
El enfoque del cliente es importante para el desarrollo de la web
Optimizacin de imgenes
Podemos utilizar PageSpeed de Google
Podemos instalar algn software como trimage:
16
Imagen
Retocar imgenes
En ocasiones es bueno retocar las imgenes:
Brillo, contraste, reduccin de ruido
Recortar la imagen para centrar la atencin en una parte de ella.
Alinear horizonte, ojos rojos....
Utilizaremos programas como photoshop o gimp.
Tipos de imgenes
Imgenes de mapa de bits:
Estn formadas por un conjunto de puntos (pxeles) contenidos en una tabla.
Cada uno de estos puntos tiene un valor o ms que describe su color.
Se modifican mediante Gimp o Photoshop
Imgenes vectoriales:
Representaciones de entidades geomtricas tales como crculos, rectngulos o segmentos.
Estn representadas por frmulas matemticas (un rectngulo est definido por dos
puntos; un crculo, por un centro y un radio...)
Se modifican mediante Inkscape o CorelDraw
Imgenes en dispositivos
til para dar un aspecto ms moderno y tecnolgico
Muy usado en programas de software, mostrando por ejemplo una aplicacin dentro de un ipad
Desde nuestro SO podemos capturar la pantalla o ventana actual y existen servicios que nos
generan nuestra imagen en un dispositivo fsico:
http://placeit.breezi.com
http://mockuphone.com
http://developer.android.com/distribute/promote/device-art.html
Tambin podemos hacerlo a mano:
http://goo.gl/aLuT6e
Especificar el nivel de compresin para imgenes jpg (de 0 a 100, por defecto 92):
Procesos en batch:
En este caso rotamos todas las imgenes de tipo png del directorio actual 90 y las
guardamos con el prefijo "rotated"
18
Video
Video
Video
Historia
Antes de html5 no haba ningn estndar para el video.
Se recurra a plugins como QuickTime, RealPlayer o Flash.
Ahora es tan sencillo como aadir la etiqueta video:
Insercin de video
Desgraciadamente la etiqueta video no funciona en todos los navegadores
Se pueden indicar varios sources por si el navegador no es capaz de reproducir uno de ellos
El navegador lo intentar con el primero, luego con el segundo....
<!DOCTYPE HTML>
<html>
<body>
</body>
</html>
<source lang="html4strict">
<video controls>
<source src="devstories.webm"
type='video/webm;codecs="vp8, vorbis"'/>
<source src="devstories.mp4"
type='video/mp4;codecs="avc1.42E01E, mp4a.40.2"'/>
</video>
</source>
Video containers
19
Video
Muchas veces pensamos en un fichero .avi o .mp4 como si fuera un video, pero realmente es un
formato contenedor.
Un fichero contenedor es como un fichero .zip y en el caso del video contiene un stream de
video y otro de audio.
El fichero contenedor define como almacenar los streams de audio y video en un solo fichero.
Aunque no es tan fcil: No todos los streams de video son compatibles con todos los ficheros
contenedores.
Video Codecs
Los streams de video y audio se codifican y se almacenan en un container.
A la hora de reproducirlos, primero el reproductor debe interpretar el formato del container y
luego decodificar el video y el audio
Cuando hablamos de un codec de video nos referimos tanto un algoritmo de COdificacin
como al de DECodificacin
Los codec de video ms populares son H264, Theora y VP8.
H264
THEORA
VP8
20
Audio
Audio
Audio
Voces de Audio
Pueden ser caras:
250 euros por 5 minutos de voz.
El equipo de audio no lo pones tu :-)
http://www.voices.com/ Elegir una voz
Te suena?
Audio Codecs
Como los codecs de video existen con o sin prdida
Como en los de video, para la web nos interesan los que tienen perdida (pero a su vez menor
peso)
Nos centraremos en los codecs generales (hay especficos por ejemplo para telefona).
Al descodificar el audio mandamos los datos del stream de audio a los altavoces
Los audios tienen canales (los videos no): cada altavoz se alimenta de un channel del stream de
audio.
Los codecs de propsito general codifican normalmente 2 canales.
En la web se utilizan exlusivamente tres codecs: MP3, AAC y Vorbis.
MP3
AAC
VORBIS
22
Qu funciona en la web
Qu funciona en la web
Qu funciona en la Web?
Formatos para la web
En el 2010 por temas de compatibilidad era necesario usar ms de un formato
MP4: Principalmente para IE y Safari
WebM: Opera, Firefox y Google Chrome
Ogg: Opera, Firefox y Google Chrome
El formato WebM se basa en una versin restringida del formato contenedor Matroska. Siempre
utiliza el cdec de vdeo VP8 y el cdec de audio Vorbis.
Codificacin de Vdeo
livav o ffmpeg? Ver resumen de problemtica
Por defecto Ubuntu funciona con livav.
Instalacin de ffmpeg
Codificacin con H.264
Codificacin con WebM y Ogg
Otra opcin es usar handbrake (est en los repositorios)
Videos responsivos
css habitual
En html5 es bueno definir solo la anchura para que el vdeo mantenga su proporcin:
23
Qu funciona en la web
Mediante css:
video {
width: 100% !important;
height: auto !important;
}
Tambin se puede usar object y embed para insertar cdigo no html. Por ejemplo youtube con
Flash:
En desuso
24
Qu funciona en la web
25
La Web actual
La Web actual
La web actual
Los objetivos de este captulo son los siguientes:
26
La Web actual
La Web actual
La web actual
Evolucin de la Web
Como era la web
La web en la actualidad
27
La Web actual
La web en el futuro
https://developers.google.com/webmasters/mobile-sites/
Curso gratuito Udacity, de Google
Oportunidades de negocio
Google da ms ranking (SEO) para bsquedas desde mviles a las webs con diseo
especfico para mviles (a partir de Abril 2015)
Comprueba si una web est optimizada para mviles
Usabilidad
El usuario puede acceder tambin a la versin desktop, especialmente si esta ltima tiene
ms funcionalidad
La redireccin a la versin desktop se debe hacer entra pginas, no al nivel principal de la
web.
SEO
Layout fluido:
La web se adaptaba al dispositivo
til al existir pantallas de PC con distintas resoluciones y formatos
29
La Web actual
Diseo adaptativo:
Los elementos de la web se adaptan (recolocan) mediante CSS en funcin del tipo de
dispositivo.
Men arriba en vez de lateral
Texto y todos a distinta altura
Diseo responsivo:
Diseo adaptativo y fluido
viewport
Qu es el viewport?
Etiqueta meta introducida por Apple, y luego adoptada y desarrollada ms all por otros.
Se traduce como ventana grfica
Indica al navegador cmo ajustar la pgina web para verse en el terminal:
El terminal "miente" sobre el tamao de su pantalla
Realiza escalado
Dentro del atributo content se pueden colocar mltiples valores delimitados por comas.
30
La Web actual
Cuando no se especifica una ventana grfica en una pgina, los navegadores para mviles
mostrarn esa pgina con un ancho alternativo que ir desde los 800 hasta los 1024 pxeles
CSS.
El factor de escalado de pgina se ajusta de modo que la pgina quepa en la pantalla, lo que
obliga a los usuarios a hacer zoom para interactuar con la pgina.
Para compatibilidad/usabilidad con los sitios web, los iPhone pedan una ventana grfica de
980px.
Pxeles
31
La Web actual
Si miramos la imagen "de cerca" veramos que est compuesta de muchos pxeles:
Est claro que no es lo mismo un monitor de 24'' con resolucin 1920x1080 que la pantalla de un
telfono mvil con 4K. Una imagen que en uno se ve bien, en el otro se vera extremadamente
pequea. Tendremos que trabajar con pxeles lgicos en vez de fsicos en nuestro CSS
Pixel CSS:
Unidad utilizada en el diseo de pgina que controla la ventana grfica.
Las dimensiones en pxeles incluidas en estilos como width: 100px se especifican en
pxeles CSS.
La proporcin entre pxeles CSS y pxeles independientes del dispositivo constituye el
factor de escalado de la pgina o el zoom.
window.devicePixelRatio
Propiedad initial-scale
Normalmente no la tocaremos
Por qu lo indicamos?
zoom
32
La Web actual
Otras propiedades:
minimum-scale
maximum-scale
user-scalable
Se suelen utilizar tan solo en aplicaciones web embebidas.
Eliminar la posibilidad del zoom limita la accesibilidad.
Media Queries
Hasta CSS3
Mediante css:
@media print {
body { font-size: 10pt }
}
@media screen {
body { font-size: 13px }
}
@media screen, print {
body { line-height: 1.2 }
}
Mediante html:
Media Queries
@media <media-query> {
/* media-specific rules */
}
{ ... }
Fluid Layout
Unidades de medida
Si queremos trabar en em, una buena opcin es que la conversin de px a ems sea sencilla:
<h1>
Ttulo de mi pgina web <a href="#">y enlace a otro sitio</a>
</h1>
h1 {font-size: 30px;
font-weight: bold;}
h1 a {font-size: 14px;}
Inconvenientes de ems
De clculo:
Unidades rem
root em = rem
El context es siempre el font-size del elemento raz
Los calculos pueden ser ms fciles
Hacemos 1em = 10px
La proporcin anterior nos sirve para cualquier elemento
Otra opcin es utilizar una medida relativa al view port (sirve tambin para PC's)
Con esta opcin es muy facil crear un botn que ocupe 1/3 de la pantalla:
Grids
Normalmente para colocar los elentos en nuestra pgina utilizaremos rejillas o grids
Display flex
Colocar elementos de 1 en 1 mediante filas o columnas flexibles
Ver soporte actual en los navegadores
Bootstrap 4 lo pondr como opcin
Gua para utilizar flexbox
{display: flex;}
Actualmente es preferible un nico sitio web (diseo adaptativo) que se adapta a los
dispositivos
Mejor para el cliente (SEO)
Mejor para el desarrollador (menos trabajo)
Mejor para Google
Breakpoints
36
La Web actual
Diseo responsivo
Imgenes y Video
Consideraciones bsicas de CSS
img {
max-width: 100%;
}
Tipos de imgenes
Retina Display
Nombre dado por Apple a pantallas con una densidad mayor de lo habitual
Nos harn falta imgenes con una densidad de pxeles mayor (1,5x-2x)
Imgenes mayores (1,5x a 2x) = Tiempos de carga mayores
Habr que cargar este tipo de imgenes tan solo cuando sea necesario
Se suelen nombrar con un sufijo "@2x", antes de la extensin.
Imgenes de contenido
Imgenes decorativas
.box{
background:url('images/box-bg.png') no-repeat top left;
37
La Web actual
width:200px;
height:200px
}
@media
only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and ( min--moz-device-pixel-ratio: 2),
only screen and ( -o-min-device-pixel-ratio: 2/1),
only screen and ( min-device-pixel-ratio: 2),
only screen and ( min-resolution: 192dpi),
only screen and ( min-resolution: 2dppx) {
.box{
background:url('images/[email protected]') no-repeat top left;
background-size: 200px 200px;
}
}
Si queremos hacer un debug de un sitio web colgado en nuestro PC, deberemos hacer un port
forwarding
Habilitaremos un puerto en el movil que se redireccionar al puerto local del servidor web
38
La Web actual
python -m SimpleHTTPServer
En node:
39
Proyecto Web bsica
Antes de empezar
Realiza un fork de mi repositorio , as podr hacer un seguimiento de tu trabajo.
Descarga el proyecto de tu repositorio ya sea mediante git clone o descargando el zip desde GitHub
Requerimientos generales
Realiza un commit por cada cambio o cambios relacionados que realices en el proyecto. Los mensajes
de los commit tienen que ser claros. Cuelga tu desarrollo en un sitio web y proporciona la URL.
Requerimientos especficos
Crea un sitio web con las siguientes caractersticas:
Est compuesto de 3 pginas: index.html, cervezas.html y contacto.html
Las pginas deben seguir el layout que te proporciono.
La pgina inicial tendr las ltimas noticias (fichero noticias.txt)
La segunda pgina tendr un listado de tus cervezas preferidas (fichero cervezas.json o
cervezas.txt)
La tercera pgina ser un formulario de contacto para aadir cervezas
Tanto el men como el resto de la pgina debe verse bien en dispositivos mviles con los
siguientes requisitos:
El diseo deber ser mobile first
El contenido se debe colocar apilado en vista mviles
El sitio web debe validarse segn la W3C.
No puedes ayudarte de ningn framework ni js (salvo el js que yo te proporciono para el
men)
Para realizar el men responsivo puedes ayudarte del fichero menu.md que te proporciono.
Pgina de inicio:
40
Proyecto Web bsica
Formulario de contacto:
41
Proyecto Web bsica
Vista movil:
42
Proyecto Web bsica
43
Tiempo de carga
Tiempo de carga
Tiempo de carga de un sitio web
Latencia
Elige un servidor adecuado comprobando la respuesta a comandos como ping o httping.
El tiempo de latencia influye y mucho en el load time de la pgina
Busca un hosting en Europa, no necesariamente Espaa, pero evita "saltar el charco".
Usa ingeniera inversa. Averigua el proveedor de hosting de la competencia
El buscador bing mediante el comando ip: xx.xx.xx.xx da informacin sobre virtual hosting.
Tambin puedes usar webs del tipo domaintools.com (de pago).
El tiempo de carga y la performance de una pgina web es muy importante para la experiencia
de usuario (UX).
Si tu web es lenta, no solo pierdes visitas, sino potenciales clientes.
Buscadores como Google tienen en cuanta la velocidad de carga de las webs para sus ranking
de bsqueda.
Cada milisegundo es importante!
Imgenes
Uso de atributos: texto alternativo (alt), ttulo de la imagen (title) y width y height.
Elige el formato correcto de las imgenes: JPG para imgenes grandes y llenas de colores. GIF
y PNG para el resto.
Nombres de ficheros de imgenes descriptivos (SEO) y en la medida de lo posible con links (al
usuario le gustan y a google tambin).
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAA
div.menu {
background-image: url('elephant.png');
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAA
SuQmCC');
}
Uso de CDN
Es importante la proximidad del servidor web al usuario
Un CDN propio es una solucin cara. Necesitamos clientes globales para que tenga sentido.
Con clientes locales ser importante escoger un servidor web con un buen tiempo de respuesta:
pocos saltos de red, cercano.
Un CDN es sencillo de implementar, pero si nuestra aplicacin tiene escrituras a BBDD, el
diseo de la arquitectura distribuida puede ser muy complejo.
Los servidores web indican el tiempo que tiene que estar almacenado en la cache mediante
alguna de las siguientes cabeceras:
Last Modified
ETag
Expires
Max-Age
Uso de gzip
Desde HTTP/1.1 los navegadores pueden indicar en las cabeceras http los formatos de
compresin que soportan:
Content-Encoding: gzip
45
Tiempo de carga
Muchos navegadores no renderizan las pginas hasta que no leen todos los css:
47
CSS avanzado
CSS avanzado
CSS
Los objetivos de este captulo son los siguientes:
Comprender las ventajas de un lenguaje de preprocesado (Sass o Less) frente a escribir CSS
directamente.
Aprender a usar y personalizar un framework de frontend como Bootstrap
Montar un entorno de trabajo en el que poder trabajar con nuestros ficheros fuentes y compilar
nuestra versin de produccin.
Comprender la evolucin de CSS hacia los web components.
48
Lenguajes de preprocesado: Sass
Qu es Sass?
Ficheros
Sintxis
Comentarios
Importar ficheros
49
Lenguajes de preprocesado: Sass
Fichero aplication.scss:
/* Mi hoja de estilos */
// tendr el contenido de todo el css de mi aplicacin
// dividido en varios ficheros scss para tener todo organizado
// No hace falta extensin, se sobreentiende scss
@import "buttons";
@import "labels";
...
Partials
Selectores anidados
#header {
height: 72px;
background: $header-background-color;
h1 {
color: white;
a {
display: block;
text-decoration: none;
}
}
Propiedades anidadas
.btn {
text: {
decoration: underline;
transform: lowercase;
}
}
50
Lenguajes de preprocesado: Sass
.btn {
&.btn-large {
width: 100px;
// seleccionamos elementos que tengan class="btn btn-large"
}
}
a {
text-decoration: none;
&:hover { color: #ccc}
&:active {color: #ddd}
}
Variables
body {
color: $base-color;
background-color: #back-color;
}
Otro ejemplo:
/*app.scss*/
$rounded: 5px;
@import "buttons"
/*_buttons.scss*/
$rounded: 3px !default;
.btn {
border-radius: $rounded;
}
Interpolacin
$elemento = header;
#{$elemento} {
background-color: red;
}
Mixins
Extends
.icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
.error-icon {
@extend .icon;
/* error specific styles... */
}
.info-icon {
@extend .icon;
/* info specific styles... */
}
.error-icon {
/* error specific styles... */
}
.info-icon {
/* info specific styles... */
}
Placeholders
52
Lenguajes de preprocesado: Sass
%icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
.error-icon {
@extend %icon;
/* error specific styles... */
}
.info-icon {
@extend %icon;
/* info specific styles... */
}
.error-icon, .info-icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
.error-icon {
/* error specific styles... */
}
.info-icon {
/* info specific styles... */
}
@mixin icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
.error-icon {
@include icon;
/* error specific styles... */
}
.info-icon {
@include icon;
/* info specific styles... */
}
53
Lenguajes de preprocesado: Sass
Funcionalmente es lo mismo que usando un placeholder, pero el CSS tiene cdigo repetido:
.error-icon {
transition: background-color ease .2s;
margin: 0 .5em;
/* error specific styles... */
}
.info-icon {
transition: background-color ease .2s;
margin: 0 .5em;
/* info specific styles... */
}
@function
@if
@else
@else if
@each
@for
@while
Operaciones matemticas
Funciones de color
Evitan usar programas de imgenes para obtener los cdigos hexadecimales de los colores
.lighten {
color: lighten($color, 20%)
}
.darken {
color: darken($color, 20%)
}
54
Lenguajes de preprocesado: Sass
55
JavaScript
JavaScript
JavaScript
Los objetivos de este captulo son los siguientes:
56
Caractersticas generales
Caractersticas generales
Caractersticas generales de JavaScript
Versiones de JavaScript
ES5:
Desde el 2009.
La entienden todos los navegadores.
ES6 o ES2015:
Finalizada en Julio 2015, despus de 6 aos!
Soporte incompleto por los navegadores (hay que usar un transpiler: Babel)
Gua de ES2015
ES7
Ya no se llamar asi
Se crean propuestas que se van aprobando y aadiendo al lenguaje.
As tenemos stages:
Stage 0 - Strawman
Stage 1 - Proposal
Stage 2 - Draft
Stage 3 - Candidate
Stage 4 - Finished
Ms info: http://www.2ality.com/2015/11/tc39-process.html
57
Caractersticas generales
LLamadas sncronas
Hasta que no acaba una instruccin, no empieza la siguiente
Ver ejemplo
No se ejecuta ms JavaScript, en segn que casos puede parecer que est "colgado"
Normalmente no es problema:
Las instrucciones se ejecutan con rapidez (equipos rpidos)
Pero a veces s:
Llamadas a API
Lectura de disco
....
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JavaScript es single thread</title>
</head>
<body>
<button>Pulsa aqu </button>
<script>
$('button').click(function () {
var answer = prompt("Cmo te llamas?");
console.log(answer);
});
$('button').click(function () {
console.log("Bienvenido");
});
</script>
</body>
</html>
JavaScript es asncrono
Se pude ejecutar una instruccin antes de que acabe la anterior, Ver ejemplo
Anlisis del ejemplo:
En el event handler hay dos funciones:
La primera es asncrona y no evita que otro cdigo se ejecute en el navegador:
console.log ("Peticin realizada")
O la propia renderizacin en el navegador (css o html)
La segunda es una funcin de callback
No se ejecuta hasta que acaba la funcin asncrona
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JavaScript: llamadas asncronas</title>
58
Caractersticas generales
</head>
<body>
<button>Pulsa aqu </button>
<script>
$('button').click(function() {
$.get('http://www.media.formandome.es/phonegap/tutorial/futbolistas.php'
console.log("Peticin contestada:", data);
});
console.log ("Peticin realizada");
})
</script>
</body>
</html>
Dificiles de detectar
Dificiles de replicar
59
linters
linters
Linters en JavaScript
Herramientas que realizan la lectura del cdigo fuente
Detectan errores/warnings de cdigo
Variables sin usar o no definida, llave sin cerrar...
Detectan fallos de estilo
Comillas dobles en vez de simples, espacios en vez de tabulaciones...
JSLint
JSLint es un analizador online de cdigo javaScript creado por Douglas Crockford
Los criterios evaluados corresponden a los que marc su creador
Demasiado estricto
No es configurable o extensible
JSHint
- Fork de JSLint
- El objetivo de JSHint es no imponer un convenio particular
- La gente utiliza diferentes estilos y convenciones.
- El linter debe adaptarse al desarrollador y no al revs
JSCS
- Solo para verificar el estilo del cdigo
- Tiene muchas reglas. No hace falta defirlas, podemos utilizar un [preset](ht
ESLint
- El ltimo en llegar (2013), recoge lo bueno de los anteriores
- Podemos [fijar nuestras reglas](http://eslint.org/docs/rules/) e incluso lue
- Y adems tiene soporte para ES6 y para JSX (que se usa en React)
- Ser el que usemos :-)
60
jQuery
jQuery
jQuery
Qu es jQuery?
jQuery es una librera de funciones JavaScript: Write less, do more
Versiones de jQuery
Existen dos ramas, la 1.x y la 2.x. Se pueden descargar de la web de jQuery
Qu rama utilizamos?
En principio se pens que la rama 2.x podra tener mucho menos peso, al quitar dependencias
con navegadores antiguos. Sin embargo, surgieron dependencias con los navegadores de los
mviles y la ganancia en kilobytes no fue significativa, en torno a un 10%.
Por otra parte el porcentaje de usuarios con versiones 6, 7 y 8 de Internet Explorer es muy bajo.
Una vez seleccionada la rama hay que elegir si queremos la versin de desarrollo o la versin de
produccin.
Versin de produccin
El fichero tiene el sufijo min: jquery-2.2.3.min.js
Est comprimida (minified)
Aproximadamente 90KB
Versin de desarrollo
Sin comprimir
Aproximadamente 3 veces ms pesada, en torno a 270KB
CDN
CDN son las siglas de Content Delivery Network. Son un grupo de servidores repartidos por todo el
mundo en puntos estratgicos y pensados para la distribucin de ficheros.
Cuando contratamos un hosting para alojar un sitio web, es habitual que nos oferten el uso de algn
CDN para colgar principalmente contenido esttico.
Para las libreras ms conocidas es frecuente que empresas como Google o Microsoft nos ofrezcan sus
CDNs.
Si el usuario navegada por varias pgina que utilizan el mismo CDN (mismo src),solo lo descarga una
vez, ya que podr usar la cach del navegador.
El evento load siempre es posterior: una vez cargado todo el DOM puede ser que se deba cargar el
contenido de algn iframe, banner de anuncios, imgenes...
Casi siempre que utilizamos jQuery nos hace falta acceder a algn elemento de nuestra pgina.
Cmo hacemos para asegurarnos de que dicho elemento ya est cargado?
Mediante JavaScript
window.onload = function(){ /*Aqu viene mi cdigo de javascript*/ }
Aunque mi cdigo est situado en el head de la pgina, no se ejecutar mi funcin hasta que se
produzca el evento load de la pgina. Ventajas:
Puede que tarde mucho en ejecutarse nuestro cdigo en JavaScript, por ejemplo si hay
imgenes pesadas o la conexin es lenta.
Actividad
Crea una pgina web con un enlace que muestre un alert con el texto "Hola Mundo" y que "anule" el
enlace.
Solucin
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hola Mundo en javaScript</title>
<script type="text/javascript">
window.onload = function() {
document.getElementById("holamundo").onclick = holaMundo;
}
function holaMundo()
{
alert ("Hola Mundo");
return false;
}
</script>
</head>
<body>
<a id="holamundo" href="http://jquery.com/">jQuery</a>
</body>
</html>
Mediante jQuery
jQuery define un nuevo evento, el evento ready para el documento html. El evento ready se produce
cuando el DOM est cargado, aunque no estn renderizados algunos elementos de la pgina. Ojo al
efectuar acciones sobre imgenes si no estn todava cargadas!
$(document).ready(function(){
// Aqu viene mi cdigo jQuery o JavaScript
});
Actividad
$("a").click(function(event) {
alert("Hola Mundo");
event.preventDefault();
});
Solucin
<!DOCTYPE html>
<html lang="en">
<head>
63
jQuery
<meta charset="utf-8">
<title>Hola Mundo con jquery</title>
<script src="jquery-1.10.2.min.js"></script>
<script>
$(document).ready(function() {
$("a").click(function(event) {
alert("Hola Mundo");
event.preventDefault();
});
});
</script>
</head>
<body>
<a href="http://jquery.com/">jQuery</a>
</body>
</html>
Sintaxis de jQuery
En una expresin de jQuery hay 3 partes:
<!DOCTYPE html>
<html>
<head>
<script src="jquery.js"></script>
<script>
64
jQuery
var jq=jQuery.noConflict();
jq(document).ready(function(){
jq("button").click(function(){
jq("p").hide();
});
});
</script>
</head>
<body>
<p>Esto es un prrafo.</p>
<button>Pulsa aqu</button>
</body>
</html>
65
Efectos en jQuery
Efectos en jQuery
Efectos
Son una forma muy visual para entrar en contacto con dos caractersticas muy importantes en jQuery:
Funciones
Utilizaremos las siguientes funciones:
$(selector).hide(speed,callback)
$(selector).show(speed,callback)
$(selector).toggle(speed,callback)
$(selector).slideDown(speed,callback)
$(selector).slideUp(speed,callback)
$(selector).slideToggle(speed,callback)
$(selector).fadeIn(speed,callback)
$(selector).fadeOut(speed,callback)
$(selector).fadeToggle(speed,callback)
$(selector).fadeTo(speed,opacity,callback)
Para ver todas las opciones de efectos consulta la api de efectos de jquery
El primer parmetro nos indica la velocidad y puede tener los valores: slow, fast, normal o
milisegundos.
El segundo parmetro es la funcin que hay que ejecutar en el momento en que se complete la
accin de hide o show.
Los parmetros son opcionales
Funcin animate
$(selector).animate({
left:'250px',
opacity:'0.5',
height:'150px',
width:'150px'
});
66
Efectos en jQuery
$("button").click(function(){
$("div").animate({
left:'250px',
height:'+=150px',
width:'+=150px'
});
});
$(selector).stop(stopAll,goToEnd);
Funciones de callback
JavaScript es asncrono. Como en otros lenguajes, se ejecutan las instrucciones lnea a lnea. Sin
embargo puede ser que una sentencia no haya terminado su ejecucin y ya haya comenzado la
siguiente:
$("p").hide(1000);
alert("El prrafo se ha escondido AHORA?");
En JavaScript las funciones son ciudadanos de primer orden y se pueden pasar como parmetros. Para
evitar el comportamiento asncrono entre las dos instrucciones anteriores, pasaremos la segunda
instruccin como parmetro de la funcin hide. Para hacer esto tendremos que embeberla en una
funcin:
$("p").hide(1000,function(){
alert("El prrafo se ha escondido AHORA");
});
En el ejemplo anterior estamos pasando como parmetro una funcin annima, pero podramos
haberla definido anteriormente guardndola en una variable:
Encadenar mtodos
Si tenemos que ejecutar varios mtodos o acciones sobre el mismo elemento, se pueden encadenar, de
modo que el elemento se busque mediante el selector de jQuery una nica vez.
$("#p1").css("color","red").slideUp(2000).slideDown(2000);
$("#p1").css("color","red")
.slideUp(2000)
.slideDown(2000);
67
Efectos en jQuery
68
html y jQuery
html y jQuery
html y jQuery
Manipulacin del contenido html
Cambia el contenido del elemento/s html seleccionado/s:
$(selector).html(contenido)
$(selector).append(content)
$(selector).prepend(content)
$(selector).after(content)
$(selector).before(content)
$("a").each(function(i){
var titulo = $(this).attr("title");
alert("Atributo title del enlace " + i + ": " + titulo);
});
Mtodo prop()
$(elemento).prop("checked", true);
Manipulacin de css
69
html y jQuery
//$(selector).css(name)
$(this).css("background-color");
//$(selector).css(name,value)
$("p").css("background-color","yellow");
//$(selector).css({properties})
$("p").css({"background-color":"yellow","font-size":"200%"});
//$(selector).height(value)
$("#div1").height("200px");
//$(selector).width(value)
$("#div2").width("300px");
Formularios
Funcin val(): para obtener los valores de los elementos o inicializarlos.
En caso de inicializar varios valores a la vez (por ejemplo un select mltiple), los pondremos
entre corchetes:
<!DOCTYPE html>
<html>
<head>
<script src="jquery.js"></script>
<script>
$(document).ready(function(){
$("#btn1").click(function(){
alert("Text: " + $("#test").text());
});
$("#btn2").click(function(){
alert("HTML: " + $("#test").html());
});
70
html y jQuery
});
</script>
</head>
<body>
<p id="test">Texto con <b>negrita</b></p>
<button id="btn1">Ver texto</button>
<button id="btn2">Ver html</button>
</body>
</html>
71
Eventos
Eventos
Eventos
Como funcionan los eventos en jQuery
$(".mienlace").click(function(mievento){
mievento.preventDefault();
alert("Has hecho clic. Como he hecho preventDefault, no te llevar al href"
});
El evento se define sobre todos los objetos seleccionados mediante el selector jQuery
En este caso todos los elementos con class="mienlace"
El tipo de evento lo definimos mediante la funcin click u otra similar.
El evento recibe como parmetro una funcin que ser la manejadora del evento.
La funcin manejadora del evento tiene a su vez un parmetro mievento que nos permite utilizar
las propiedades o mtodos del evento en cuestin.
En este caso utilizaremos el mtodo preventDefault()
Listado de Eventos
Eventos relacionados con el ratn
click()
dblclick()
mousedown()
Para generar un evento cuando el usuario hace clic independientemente de si lo suelta o
no.
Sirve tanto para el botn derecho como el izquierdo del ratn.
til para drag&drop
$("#p").mousedown(function (b) {
alert(b.which);
//b puede ser 1, 2 o 3 (botn izquierdo, central o derecho)
});
mouseup()
Para generar un evento cuando el usuario ha hecho clic y luego suelta un botn del ratn.
El evento mouseup se produce slo en el momento de soltar el botn.
mousemove()
Evento que se produce al mover el ratn sobre un elemento de la pgina.
72
Eventos
$("#contendedor").mousemove(function (c) {
$(this).html("El ratn se est moviendo. Las coordenadas son " +
});
mouseover() y mouseout()
Sirve para lo mismo que los eventos mouseover y mouseout de Javascript. Se produce
cuando el ratn est sobre un elemento, pero tiene como particularidad que pueden
producirse varias veces mientras se mueve el ratn sobre el elemento, sin necesidad de
haber salido (por los elementos anidados).
mouseenter() y mouseleave()
Normalmente preferiremos estos eventos respecto a los originales de javascript ya que se
ejecutarn slo una vez.
hover()
Esta funcin en realidad sirve para manejar dos eventos, cuando el ratn entra y sale de
encima de un elemento. Por tanto espera recibir dos funciones en vez de una que se enva
a la mayora de los eventos.
A menudo utilizaremos este evento mejor en vez de mouseenter() y mouseleave().
.hover(function() {
Put in mouse enter function here
}, function() {
Put in mouse leave function here
});
//Ejemplo:
$("#p").hover(function () {
$(this).css("background-color", "blue");
}, function () {
$(this).css("background-color", "white");
});
toggle()
Sirve para indicar dos o ms funciones para ejecutar cuando el usuario realiza clics, con
la particularidad que esas funciones se van alternando a medida que el usuario hace clics.
$("#p").toggle(function () {
$(this).css("background-color", "blue");
}, function () {
$(this).css("background-color", "red");
}, function () {
$(this).css("background-color", "yellow");
});
keydown()
Se produce en el momento que se presiona una tecla del teclado, independientemente de
si se libera la presin o se mantiene.
Funciona con todas las teclas.
73
Eventos
keyup()
Se ejecuta en el momento de liberar una tecla.
Funciona con todas las teclas.
keypress()
Se ejecuta como respuesta a una pulsacin e inmediata liberacin de la tecla.
No se dispara con las teclas ALT, MAYS, CTRL.
Los navegadores almacenan de forma diferente las teclas pulsadas. La propiedad which del
evento nos permitir trabajar sin preocuparnos de ello.
Ejemplo:
<html>
<head>
<script type="text/javascript" src="jquery-1.8.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#keypress").keyup(function (key) {
alert(key.which);
});
});
</script>
</head>
<body>
<p>Key Up Test: <input type="text" name="keypress" id="keypress" /></p
</body>
</html>
En la versin de jQuery 1.7 han intentado unificar las APIs de manejo de eventos en los
mtodos on() y off().
Estos mtodos sustituyen a los antiguos bind(), delegate() y live().
Mtodo on()
Las funciones para eventos vistas hasta ahora, como click, son atajos a la funcin on():
Estas dos construcciones son equivalentes, pero on() permite hacer muchas ms cosas...
74
Eventos
Permite usar un mismo manejador de eventos para mltiples elementos html suscribiendo el
manejador a un elemento padre. Dado el siguiente cdigo html:
<div id="content">
<a href="#">enlace1</a>
<a href="#">enlace2</a>
<a href="#">enlace2</a>
</div>
Si queremos asignar el mismo manejador de eventos a todos los enlaces, podemos hacerlo de la
siguiente forma:
Ventajas:
Slo se crea una nica funcin, independientemente del nmero de enlaces que
tengamos, reduciendo el consumo de recursos.
Es vlido para elementos que no existen todava. Si apareciese un nuevo elemento a
dentro del div, automticamente estaramos manejando su evento click. Esto es
especialmente til cuando generamos html dinmicamente.
Mtodo off()
Para esta accin, contbamos con varios mtodos como unbind(), die() o undelegate().
De nuevo, el objetivo principal de la nueva instruccin es reemplazarlos a todos de un modo
consistente.
La sintaxis de off() resulta similar a la de on():
Con off(), todos los parmetros son opcionales. Cuando se utiliza en su forma ms simple,
$(elements).off(), se eliminan todos los eventos asociados al conjunto seleccionado.
Ejemplo
<!DOCTYPE html>
<html>
<head>
75
Eventos
<style>
button { margin:5px; }
button#theone { color:red; background:yellow; }
</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
<button id="theone">Does nothing...</button>
<button id="bind">Add Click</button>
<button id="unbind">Remove Click</button>
<div style="display:none;">Click!</div>
<script>
function aClick() {
$("div").show().fadeOut("slow");
}
$("#bind").click(function () {
$("body").on("click", "#theone", aClick)
.find("#theone").text("Can Click!");
});
$("#unbind").click(function () {
$("body").off("click", "#theone", aClick)
.find("#theone").text("Does nothing...");
});
</script>
</body>
</html>
76
Ajax
Ajax
Ajax
JSON
JavaScript Object Notation
Se utiliza para almacenar e intercambiar informacin
Ms pequeo que XML y ms rpido y sencillo de analizar (parsear).
Se basa en la sintaxis del propio JavaScript para objetos.
//Objeto JSON:
{ "nombre":"Pepe" , "apellido":"Prez" }
Otros ejemplos:
//Array JSON
{
"estudiantes": [
{ "nombre":"Juan" , "lastName":"Alcocer" },
{ "nombre":"Ana" , "lastName":"Serrano" },
{ "nombre":"Mario" , "lastName":"Gil" }
]
}
//sintxis en JavaScript:
var estudiantes = [
{ "nombre":"Juan" , "lastName":"Alcocer" },
{ "nombre":"Ana" , "lastName":"Serrano" },
{ "nombre":"Mario" , "lastName":"Gil" }
];
Qu es AJAX?
AJAX quiere decir Asynchronous JavaScript and XML.
Sirve para cargar datos en background y mostrarlos en la web sin necesidad de recargar la
pgina, por eso lo de asncrono.
XHR significa XML HTTP REQUEST y es hablar de lo mismo.
Lo podemos ver en el inbox de gmail, en google maps cuando aplicamos el zoom, etc.
jQuery y AJAX:
La implementacin de AJAX es distinta en funcin del navegador.
Facilita la sintaxis para usar AJAX
Cachear AJAX
$.ajaxSetup ({
cache: false
});
navegador.
La cach solo funciona mediante GET.
Mtodo load
Es el mtodo ms sencillo. Lo usaremos para cargar cierto contenido por AJAX al DOM de la
pgina actual.
$(selector).load(URL,data,callback);
Ejemplo de uso
<html>
<head>
<title>Ajax Simple</title>
<script src="jquery-1.8.2.min.js" type="text/javascript"></script>
<script>
$(document).ready(function(){
$("#enlaceajax").click(function(evento){
evento.preventDefault();
$("#destino").load("contenido-ajax.html");
});
})
</script>
</head>
<body>
</body>
</html>
$("#div1").load("mipagina.html #p1");
En este caso obtendremos del fichero mipagina.html el elemento identificado con id="p1".
Paso de parmetros
$(document).ready(function(){
$("#enlaceajax").click(function(evento){
evento.preventDefault();
$("#destino").load("recibe-parametros.php", {nombre: "Pepe", edad: 45}
alert("recibidos los datos por ajax");
});
78
Ajax
});
})
Fichero en php:
$(document).ready(function(){
$("#enlaceajax").click(function(evento){
evento.preventDefault();
var ajax_load = "<img src='img/load.gif' alt='loading...' />";
var loadUrl = "pagina_lenta.php";
$("#result").html(ajax_load).load(loadUrl);
});
})
Fichero en php:
<?php
sleep(3);
echo ("He tardado 3 segundos en ejecutar esta pgina...");
?>
$(selector).load(URL,data, callback);
Ejemplo de uso:
$("button").click(function(){
$("#div1").load("demo_test.txt",function(responseTxt,statusTxt,xhr){
if(statusTxt=="success")
alert("External content loaded successfully!");
if(statusTxt=="error")
alert("Error: "+xhr.status+": "+xhr.statusText);
});
});
Otros mtodos
$.getJSON(): Obtiene un fichero JSON de un sitio remoto
$.getScript(): Obtiene un fichero javascript de un sitio remoto
79
Ajax
Ajax y Firebug
Podemos hacer un seguimiento de las peticiones Ajax desde la pestaa de Red de Firebug,
opcin XHR (XML HTTP REQUEST):
Si pulsamos en el recuadro del + a la izquierda, podremos ver los parmetros que se envan en
la peticin AJAX. En esta peticin no hay ningn parmetro. El nico que hay es un nmero
aleatorio generado para forzar que la peticin no se sirva de la cach.
80
Ajax
$("#load_get").click(function(){
$("#result")
.html(ajax_load)
.load(loadUrl, "language=php&version=5");
});
Si pasamos los parmetros como un objeto en vez de como una cadena, se enviarn va POST:
$("#load_post").click(function(){
$("#result")
.html(ajax_load)
.load(loadUrl, {language: "php", version: 5});
});
Mtodo .ajax
Utilizaremos ajax mediante el plugin jQuery de Sublime
Tan solo con escribir ajax dispondremos del snippet de Sublime:
$.ajax({
url: '/path/to/file',
type: 'default GET (Other values: POST)',
dataType: 'default: Intelligent Guess (Other values: xml, json, script, or h
81
Ajax
Podemos optar por utilizar promesas si la lectura asncrona del cdigo es complicada
82
Adios jQuery?
Adios jQuery?
Adios jQuery?
Un poco de historia
Hasta hace unos aos haba grandes diferencias entre navegadores:
Accediendo al DOM
Gestionando eventos
jQuery (2005)
Mootols (2007)
....
Usamos jQuery?
Respuesta rpida: NO, salvo por temas de compatibidad
Respuesta meditada:
Si realizas una web (no una webapp) SI
Dispones de muchos plugins y desarrollos ya hechos
Si realizas una webapp NO, utiliza algn framework de JS, pero analiza:
SEO? Tiempo de carga? Renderizacin en servidor?
Componentes que necesitas?
Selectores en JavaScript
Nos hemos acostumbrado a usar tanto jQuery que ahora toca volver a aprender:
A hacer las cosas con el JavaScript de antes
A utilizar nuevas funcionalidades del JavaScript de ahora
Si es nuestro caso, que venimos de un background con jQuery, merece la pena echar un ojo a
alguna gua.
Selector de clase
83
Adios jQuery?
// jQuery
$('.myClass');
// JavaScript
document.getElementsByClassName('myClass');
Selector de id
// jQuery
$('#myID');
// JavaScript
document.getElementById('myID');
Selector de etiqueta
// jQuery
$('div');
// JavaScript
document.getElementsByTagName('div');
querySelector
Eventos en JavaScript
Eventos
/*
* Click
*/
// jQuery
$(elem).on('click', function () {...});
84
Adios jQuery?
// JavaScript
document.querySelector(elem).onclick = function () {...}
Encolar eventos
document.addEventListener('click', function() {
// ...
}, false);
document.addEventListener('DOMContentLoaded', function() {
// DOM ready, run it!
}, false);
85
Node.js
Node.js
Node.js
Los objetivos de este captulo son los siguientes:
86
Introduccin a Node.js
Introduccin a Node.js
JavaScript en servidor
Qu es nodejs
NodeJS es un intrprete de JavaScript que se ejecuta en servidor.
Est basado en el motor de JavaScript que utiliza Google Chrome (V8), escrito en C++
Caractersticas principales
El tener el mismo lenguaje en cliente y servidor
Es monohilo
Utiliza un solo procesador
Si queremos usar toda la potencia de la CPU, tendremos que levantar varias instancias de
node y utilizar un balanceador de carga (por ejemplo con pm2)
87
Introduccin a Node.js
Desventajas
Trabajar con cdigo asncrono hace que a veces el cdigo no sea excesivamente legible
Imagina que guardamos un registro de los accesos de los usuarios a nuestra app:
trackUser = function(userId) {
users.findOne({userId: userId}, function(err, user) {
var logIn = {userName: user.name, when: new Date};
logIns.insert(logIn, function(err, done) {
console.log('wrote log-in!');
});
});
npm
Es el gestor de paquetes de node
Propongo hacer dos prcticas para coger la dinmica del uso de npm y sus libreras y de trabajar
con node:
Crear una librera en node.js
Crear una api rest mediante node.js
88
Introduccin a Node.js
89
Crear una librera en node.js
Microlibreras
Ventajas
Poco cdigo, se entiende y modifica con facilidad
Reusable
Fcil hacer tests
Desventajas
Tienes que gestionar muchas dependencias
Control de versiones de todas ellas
Funcionalidad librera
Obtiene una marca de cerveza y sus caractersticas
Obtiene una o varias marcas de cerveza al azar.
Control de versiones
Utilizaremos git como control de versiones
Utilizaremos github como servidor git en la nube para almacenar nuestro repositorio:
Haz login con tu usuario (o crea un usuario nuevo)
Crea un nuevo repositorio en GitHub (lo llamar cervezas)
Sigue las indicaciones de GitHub para crear el repositorio en local y asociarlo al
repositorio remoto (GitHub)
Instalacin de node
Lo ms sencillo es instalar mediante el gestor de paquetes
node -v
npm -v
npm
90
Crear una librera en node.js
Configuracin de npm
Cuando creemos un nuevo proyecto nos interesa que genere automaticamente datos como
nuestro nombre o email
Ver documentacin para su configuacin o mediante consola (npm --help) :
Mediante npm config --help vemos los comandos de configuracin
Mediante npm config ls -l vemos los parmetros de configuracin
Versiones en node
Se utiliza Semantic Versioning
Cambios de versin:
Creamos el proyecto
Dentro del directorio cervezas:
npm init
module.exports = {
todas: cervezas
}
node
> var cervezas = require('./index.js')
undefined
> cervezas.todas
npm i -S unique-random-array
cervezas = require('./cervezas.json')
var uniqueRandomArray = require ('unique-random-array')
module.exports = {
todas: cervezas,
alazar: uniqueRandomArray(cervezas)
}
git status
git add -A
git status
git commit -m "versin inicial"
Ojo que haya cogido los cambios del .gitignore para hacer el push
git push
Publicamos en npm
npm publish
node index.js
Versiones en GitHub
Nuestro paquete tiene la versin 1.0.0 en npm
Nuestro paquete no tiene versin en GitHub, lo haremos mediante el uso de etiquetas:
Modificar librera
Queremos mostrar las cervezas ordenadas por nombre
Utilizaremos la librera lodash (navaja suiza del js) para ello:
Versiones beta
Vamos a aadir una cerveza nueva, pero todava no se est vendiendo.
Aumentamos nuestra versin a 1.2.0-beta.0 (nueva funcionalidad, pero en beta)
Al subirlo a npm:
Con npm info podremos ver un listado de nuestras versiones (mir las dist-tags)
Para instalar la versin beta:
Tests
93
Crear una librera en node.js
Utiliza los paquetes Mocha Snippets y Chai Completions de Sublime Text para completar el
cdigo
Ahora prepararemos una estructura de tests algo ms elaborada:
describe('cervezas', function () {
describe('todas', function () {
it('Debera ser un array de objetos', function (done) {
// se comprueba que cumpla la condicin de ser array de objetos
done();
});
it('Debera incluir la cerveza Ambar', function (done) {
// se comprueba que incluya la cerveza Ambar
done();
});
});
describe('alazar', function () {
it('Debera mostrar una cerveza de la lista', function (done) {
//
done();
});
});
});
describe('cervezas', function () {
describe('todas', function () {
it('Debera ser un array de objetos', function (done) {
94
Crear una librera en node.js
expect(cervezas.todas).to.satisfy(isArrayOfObjects);
function isArrayOfObjects(array){
return array.every(function(item){
return typeof item === 'object';
});
}
done();
});
it('Debera incluir la cerveza Ambar', function (done) {
expect(cervezas.todas).to.satisfy(contieneAmbar);
function contieneAmbar (array){
return _.some(array, { 'nombre': 'MBAR ESPECIAL' });
}
done();
});
});
describe('alazar', function () {
it('Debera mostrar un elemento de la lista de cervezas', function (do
var cerveza = cervezas.alazar();
expect(cervezas.todas).to.include(cerveza);
done();
});
});
});
Automatizar tareas
Cada vez que desarrollamos una versin de nuestra libera:
Ejecutar los tests
Hay que realizar un commit
Hay que realizar un tag del commig
Push a GitHub
Publicar en npm
...
Vamos a intentar automatizar todo:
Semantic Release para la gestin de versiones
Travis como CI (continuous integration)
Instalacin y configuracin:
Cambios en package.json:
95
Crear una librera en node.js
Uso de commitizen
commitizen que nos ayudar en la generacin de los mensajes de los commit.
Habr que ejecutar git cz en vez de git commit para que los commits los gestione commitizen
Cambio de versin
Vamos a comprobar nuestro entorno aadiendo una funcionalidad
Si pedimos cervezas.alazar() queremos poder recibir ms de una
Los tests:
- Hagamos ahora el git cz & git push y veamos como funciona todo
- Podramos aadir un issue y hacer el fix en este commit escribiendo closes #
## Git Hooks
- Son una manera de ejecutar scripts antes de que ocurra alguna accin
- Sera ideal pasar los tests antes de que se hiciera el commit
96
Crear una librera en node.js
npm i -D ghooks
## Coverage
- Nos interesa que todo nuestro cdigo se pruebe mediante tests.
- Necesitamos una herramienta que compruebe el cdigo mientras se realizan los
npm i -D instanbul
## Check coverage
- Podemos tambin evitar los commits si no hay un porcentaje de tests ptimo:
"check-coverage": "istanbul check-coverage --statements 100 --branches 100 --functions 100 -lines
100"
script:
Grficas
Utilizaremos la herramienta codecov.io:
npm i -D codecov.io
97
Crear una librera en node.js
after success:
- npm run report-coverage
- npm run semantic-release
Por ltimo podemos aadir etiquetas de muchos servicios: npm, codecov, travis... una fuente
habitual es http://www.shields.io
98
Arquitectura de una API REST
Provedores de APIs
Algunos ejemplos de sitios web que proveen de APIS son:
Twitter: acceso a datos de usuarios, estado
Google: por ejemplo para consumir un mapa de Google
Pero hay muchos ms: Facebook, YouTube, Amazon, foursquare...
Pero todava hay muchos ms: directorio de proveedores de APIs
http://www.formandome.es/api/cursos/1
GET http://www.formandome.es/api/cursos/1
99
Arquitectura de una API REST
200 OK HTTP/1.1
404 NOT FOUND HTTP/1.1
Creacin de recursos
La URL estar abierta (el recurso todava no existe y por tanto no tiene id)
El mtodo debe ser POST
http://eventos.com/api/eventos/3/comentarios
Resultados posibles:
403 (Acceso prohibido)
400 (peticin incorrecta, p.ej. falta un campo o su valor no es vlido)
500 (Error del lado del servidor al intentar crear el recurso, p.ej. se ha cado la BD)
201 (Recurso creado correctamente)
Qu URL tiene el recurso recin creado?
La convencin en REST es devolverla en la respuesta como valor de la cabecera HTTP
Location
Actualizacin de recursos
Mtodo PUT
Segn la ortodoxia REST, actualizar significara cambiar TODOS los datos
PATCH es un nuevo mtodo estndar HTTP (2010) pensado para cambiar solo ciertos
datos. Muchos frameworks de programacin REST todava no lo soportan
Resultados posibles
Errores ya vistos con POST
201 (Recurso creado, cuando le pasamos el id deseado al servidor)
200 (Recurso modificado correctamente)
Eliminar recursos
Mtodo DELETE
Algunos resultados posibles:
200 OK
404 Not found
500 Server error
Tras ejecutar el DELETE con xito, las siguientes peticiones GET a la URL del recurso
deberan devolver 404
Arquitectura REST
Reglas de una arquitectura REST
Interfaz uniforme
Peticiones sin estado
Cacheable
Separacin de cliente y servidor
Sistema de Capas
Cdigo bajo demanda (opcional)
100
Arquitectura de una API REST
Interfaz Uniforme
La interfaz de basa en recursos (por ejemplo el recurso Empleado (Id, Nombre, Apellido,
Puesto, Sueldo)
El servidor mandar los datos (va html, json, xml...) pero lo que tenga en su interior (BBDD
por ejemplo) para el cliente es transparente
La representacin del recurso que le llega al cliente, ser suficiente para poder cambiar/borrar el
recurso:
Suponiendo que tenga permisos
Por eso en el recurso solicitado se suele enviar un parmetro Id
Mensajes descriptivos:
Usar las caractersticas del protocolo http para mejorar la semntica:
HTTP Verbs
HTTP Status Codes
HTTP Authentication
Procurar una API sencilla y jerrquica y con ciertas reglas: uso de nombres en plural
GET mi_url/empleados/1234
DELETE mi_url/empleados/1234
En la segunda peticin hemos tenido que incidar el identificador del recurso que queremos
borrar
El servidor no guardaba los datos de la consulta previa que tena el cliente en partcular.
Una peticin del tipo DELETE mi_url/empleado debe dar error, falta el id y el servidor no lo
conoce!
Cacheable
Sistema de capas
El uso de capas o servidores intermedios puede servir para aumentar la escalabilidad (sistemas
de balanceo de carga, cachs) o para implementar polticas de seguridad
Los servidores pueden ser capaces de aumentar o definir cierta funcionalidad en el cliente
transfirindole cierta lgica que pueda ejecutar:
Componentes compilados como applets de Java
JavaScript en cliente.
HTTP verbs
Si realizamos CRUD, debemos utilizar los HTTP verbs de forma adecuada para cuidar la
semntica.
GET: Obtener datos. Ej: GET /v1/empleados/1234
PUT: Actualizar datos. Ej: PUT /v1/empleados/1234
POST: Crear un nuevo recurso. Ej: POST /v1/empleados
DELETE: Borrar el recurso. Ej: DELETE /v1/empleados/1234
PATCH?: Para actualizar ciertos datos
Cdigos de estado
Formato de salida
Pero tambin es un problema, por ejemplo con AJAX: una pgina de http://localhost en
principio no puede hacer una peticin AJAX a Google
Como consecuencia, se han tenido que idear diversos trucos/tcnicas para intentar sobrepasar
este lmite
CORS
103
Arquitectura de una API REST
Mtodos de autenticacin
Qu es un token?
Normalmente un hash calculado con algn dato (p.ej. login del usuario + clave secreta)
Adems el token puede llevar datos adicionales como el login
OAuth
104
Arquitectura de una API REST
Para que una app pueda acceder a servicios de terceros sin que el usuario tenga que darle a la
app sus credenciales del servicio
Ejemplo: una app que permite publicar en tu muro de FB, pero en la que no confas lo
suficiente como para meter tu login y password de FB
Es el estndar en APIs REST abiertos a terceros
Se basa en el uso de un token de sesin
Terminologa de OAuth
Flujo en OAuth
105
Creacin de una API con node.js
Configuracin de eslint
Si tienes los linters para Sublime y js configurados, comprueba que la consola arroja un error.
npm i -D eslint
./node_modules/.bin/eslint --init
? How would you like to configure ESLint? Answer questions about your styl
? Are you using ECMAScript 6 features? No
? Where will your code run? Node
? Do you use JSX? No
? What style of indentation do you use? Spaces
? What quotes do you use for strings? Single
? What line endings do you use? Unix
? Do you require semicolons? No
? What format do you want your config file to be in? JSON
Successfully created .eslintrc.json file in /home/juanda/api_node_express/
express
Utilizaremos express para realizar la API
Instalar express mediante uno de los comandos siguientes:
Creamos el fichero app/server.js donde pondremos el cdigo necesario para testear una API
muy bsica para probar Express.
106
Creacin de una API con node.js
Si el linter de js te da un error por usar console.log, puedes deshabilitar esa regla en el fichero
de configuracin de eslint
no-console: 0
node app/server.js
Creamos una entrada en nuestro fichero package.json, de modo que podamos arrancar nuestra
API mediante npm start
Hagamos un commit del repositorio, pero sin tener en cuenta la carpeta node_modules.
Comprueba con el segundo git status que git no lo tiene en cuenta antes de continuar con el
commit:
git status
echo "node_modules">.gitignore
git status
git add -A *
git commit -m "Primera versin API"
git push
107
Creacin de una API con node.js
Debemos hacer nuevas instantneas en pasos posteriores, pero ya no las documentar por
brevedad.
nodemon
Es un wrapper de node, para reiniciar nuestro API Server cada vez que detecte modificaciones.
npm i -D nodemon
Cada vez que ejecutemos npm start ejecutaremos nodemon en vez de node. Habr que cambiar
el script en el fichero package.json:
Uso de enrutadores
Imagina que nuestra API es compleja:
Utilizaremos enrutadores
Recibir parmetros
Cuando el router recibe una peticin, podemos observar que ejecuta una funcin de callback:
A menudo la peticin se har enviando algn parmetro adicional. Hay varias posibilidades:
108
Creacin de una API con node.js
req.param.nombreVariable
npm i -S body-parser
router.post('/',function(req,res) {
res.json({mensaje: req.body.nombre})
})
//arrancamos el servidor
app.listen(port)
console.log('API escuchando en el puerto ' + port)
El fichero app/routes/index.js
router.use('/cervezas', cervezas)
module.exports = router
Y el fichero app/routes/cervezas.js:
110
Creacin de una API con node.js
Instalacin de MongoDB
Instalamos y leventamos el servicio de MongoDB:
Y para entrar a su consola, mediante mongo, o mediante algn gui como por ejemplo
Robomongo
Insercin de datos
Utilizaremos el fichero cervezas.json, lo podemos obtener mediante:
wget https://raw.githubusercontent.com/juanda99/proyecto_web_basica/master
Para poder hacer una bsqueda por varios campos de texto, tendremos que hacer un ndice:
111
Creacin de una API con node.js
db.cervezas.getIndexes()
db.cervezas.dropIndex("CervezasIndex")
Instalacin de Mongoose
Instalaremos [mongoose] como ODM (Object Document Mapper) en vez de trabajar con el
driver nativo de MongoDB (se utiliza por debajo).
npm i -S mongoose
Uso de Mongoose
Creamos el fichero app/db.js donde configuraremos nuestra conexin a base de datos mediante
mongoose:
mongoose.connection.on('connected', function () {
console.log('Conectado a la base de datos: ' + MONGO_URL)
})
mongoose.connection.on('error',function (err) {
console.log('Error al conextar a la base de datos: ' + err)
})
mongoose.connection.on('disconnected', function () {
console.log('Desconectado de la base de datos')
})
process.on('SIGINT', function() {
mongoose.connection.close(function () {
console.log('Desconectado de la base de datos al terminar la app')
process.exit(0)
112
Creacin de una API con node.js
})
})
Modelos
Definimos un esquema para nuestros objetos (cervezas) y creamos nuestro modelo a partir del
esquema (fichero app/models/Cervezas.js):
module.exports = Cerveza
Uso de controladores
Desde nuestro fichero de rutas (app/routes/cervezas.js), llamaremos a un controlador que ser el
encargado de aadir, borrar o modificar cervezas en base al modelo anterior.
Nuestro cdigo queda as perfectamente separado y cada fichero de rutas se encargar solo de
gestionar los endpoints de nuestra API para el recurso en cuestin.
Creamos un directorio especfico para los controladores, donde colocaremos el especfico para
las cervezas.
Nuestro cdigo quedas as (fichero app/controllers/cervezasController.js):
113
Creacin de una API con node.js
var id = req.params.id
Cervezas.findOne({_id: id}, function(err, cerveza){
if(err) {
return res.status(500).json({
message: 'Se ha producido un error al guardar la cerveza',
error: err
})
}
if(!cerveza) {
return res.status(404).json({
message: 'No hemos encontrado la cerveza'
})
}
cerveza.Nombre = req.body.nombre
cerveza.Descripcin = req.body.descripcion
cerveza.Graduacion = req.body.graduacion
cerveza.Envase = req.body.envase
cerveza.Precio = req.body.precio
cerveza.save(function(err, cerveza){
if(err) {
return res.status(500).json({
message: 'Error al guardar la cerveza'
})
}
if(!cerveza) {
return res.status(404).json({
message: 'No hemos encontrado la cerveza'
})
}
return res.json(cerveza)
})
})
},
remove: function(req, res) {
var id = req.params.id
Cervezas.findByIdAndRemove(id, function(err, cerveza){
if(err) {
return res.json(500, {
message: 'No hemos encontrado la cerveza'
})
}
return res.json(cerveza)
})
}
}
115
Creacin de una API con node.js
})
router.get('/', function(req, res) {
cervezasController.list(req, res)
})
router.get('/:id', function(req, res) {
cervezasController.show(req, res)
})
router.post('/', function(req, res) {
cervezasController.create(req, res)
})
router.put('/:id', function(req, res) {
cervezasController.update(req, res)
})
router.delete('/:id', function(req, res) {
cervezasController.remove(req, res)
})
module.exports = router
http://localhost:8080/api/cervezas/search?q=regaliz
...
Test de la API
Utilizaremos Mocha como test framework y supertest para hacer las peticiones http.
Creamos nuestro fichero tests/api.test.js con la prueba para crear una cerveza:
'use strict'
/* global describe it */
var request = require('supertest')
116
Creacin de una API con node.js
Utiliza los paquetes Mocha Snippets y Chai Completions de Sublime Text para completar el
cdigo
describe nos sirve para describir los test suites (se pueden anidar varios)
it nos sirve para describir cada caso de test.
requests(app).post realizar una peticin post a nuestra api
Mediante lnea de comandos (hace falta la ruta completa ya que no hemos instalado el
paquete de forma global):
node_modules/.bin/mocha tests
Introduciendolo en el fichero package.json (no hace falta la ruta al estar dentro del
package.json):
Para que el caso anterior funcione, tenemos que modificar nuestro fichero app/server de modo
que se pueda utilizar app desde otro fichero js:
Por ltimo podramos utilizar un paquete como istanbul que nos analice el cdigo y ver si
nuestras pruebas recorren todas las instrucciones, funciones o ramas del cdigo:
npm i -D istanbul
./node_modules/.bin/istanbul cover -x "**/tests/**" ./node_modules/.bin/_
Estos datos son facilmente exportables a algn servicio que nos de una estadstica de la
cobertura de nuestros tests o que haga un seguimiento de los mismos entre las distintas
versiones de nuestro cdigo.
Por ltimo tambin se podra integrar con un sistema de integracin continua tipo Travis.
Uso de middlewares
Son funciones que tienen acceso al objeto de solicitud (req), al objeto de respuesta (res) y a la
siguiente funcin de middleware en el ciclo de solicitud/respuestas de la aplicacin.
La siguiente funcin de middleware se denota normalmente con una variable denominada next.
console.log('Time:', Date.now());
next();
});
Normalmente utilizaremos middlewares que ya estn hechos, por ejemplo Morgan para logs y
cors para Cors.
Los instalamos:
app.use(morgan('combined'))
app.use(cors())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(bodyParser.json())
118
SPA
SPA
Single Page Applications
Los objetivos de este captulo son:
119
Arquitectura de un SPA
Arquitectura de un SPA
SPA
Caractersticas de un SPA
Por SPA se conocen las aplicaciones de una sola pgina o Single Page Applications.
La aplicacin se enva al navegador y la pgina no se recarga durante su uso.
Una arquitectura SPA permite realizar cualquier aplicacin tradicional de escritorio va web, ya
que el tiempo de respuesta es mucho ms rpido que el de una aplicacin web tradicional.
Arquitectura de un SPA
La mayor parte de la funcionalidad se lleva al cliente. Lo podramos ver como un fat-client que
se carga desde un servidor web.
El cdigo en servidor se usa bsicamente para proveer de una API RESTful a nuestro cdigo
120
Arquitectura de un SPA
Un poco de historia
Plataformas SPA
Las tres plataformas de SPA ms utilizadas (2014) son Java applets, Flash/Flex y JavaScript.
La mejor eleccin es JavaScript por las siguientes razones:
No necesita ningn plugin ni ninguna configuracin de seguridad adicional.
Utiliza menos recursos que introducir otro entorno de ejecucin adicional.
Una pgina ms fluida e interactiva: la interfaz de la aplicacin es la ventana completa
del navegador
Por contra JavaScript ha tardado en ser competitivo principalmente por las inconsistencias entre
los distintos navegadores.
Las otras tecnologas estn desapareciendo:
IPad 1 no ejecutaba Flash en su aparicin en el 2010
Al final del 2015, muchas empresas quitaron o anunciaron que iban a eliminar el soporte
a tecnologas como Flash, Silverlight o Java de sus navegadores.
Oracle propone a los desarrolladores de Java migrar sus applets a Java Web Start.
121
Arquitectura de un SPA
distintos navegadores
La propia evolucin de JavaScript con el uso de JSON, jQuery, AJAX y muchas libreras
actuales y potentes.
Podemos utilizar JavaScript tanto en cliente como en servidor mediante Node.js.
Existen bases de datos que pueden comunicarse directamente en JSON como CouchDB o
MongoDB
Dadas las ventajas inherentes a JavaScript hay herramientas para trabajar en otros lenguajes de
programacin y que generan posteriormente JavaScript. Un ejemplo es Google Web Toolkit
(GWT) que genera JavaScript desde Java o Cappuccino que utiliza Objective-C.
Problemas de JavaScript
Sin embargo por la naturaleza de un SPA tenamos varios inconvenientes (entre parntesis cito
posibles soluciones):
Frameworks de JavaScript
Me: Fatigued.
Saul: Family?
Avances en JavaScript
Las nueva versin de JavaScript (ES2015) ha mejorado muchas carencias del lenguaje como el
uso unificado de mdulos.
El uso de Polymer o React.js marca la tendencia a trabajar haca web components. Angular 2,
despus de mucho tiempo el 2 de Mayo de 2016 public su Release Candidate.
React.js fue la gran revelacin en el 2015 y parece que ha surgido para quedarse. Ya veremos
que ocurre con Angular2, hay quien dice que llega demasiado tarde....
122
PhoneGap
PhoneGap
PhoneGap
Introduccin
Vamos a crear una pequea prctica con la que aprenderemos las caractersticas bsicas de
Cordova, manejar la API de para usar las caractersticas nativas del dispositivo y a crear una
aplicacin con una arquitectura ptima para mviles.
Requisitos previos
En el captulo de Entorno de trabajo vimos como instalar Android Studio junto con el JDK
Desde el software de Android Studio podemos instalar los SDK de Android que necesitemos.
Se configuraron tambin los PATH de la mquina necesarios. Si tu usuario es diferente, puede
ser que tengas que cambiar algo.
ADB
ADB son las siglas de Android Debug Bridge
Es una herramienta de desarrollo incluida en el SDK de Android.
Comunica el dispositivo Android o el emulador con el ordenador.
Sirve para instalar aplicaciones, ver ficheros de log, hacer push o pull de ficheros...
Para ver errores utilizaremos:
adb logcat
Emuladores
Mediante android avd podemos definir los emuladores que necesitemos:
No olvides, en Emulation options, marcar la opcin use host GPU
npm i -g cordova
cd
cordova create proyecto com.tunombre.proyecto Proyecto
123
PhoneGap
la aplicacin. Puede ser til poner el modificador -d para mostrar el progreso de creacin del proyecto
$ cordova platform ls
Installed platforms:
Available platforms:
amazon-fireos ~3.6.3 (deprecated)
android ~5.1.1
blackberry10 ~3.8.0
browser ~4.1.0
firefoxos ~3.6.3
ubuntu ~4.3.3
webos ~3.7.0
Plugins de Cordova
Observa que en el paso anterior se ha instalado un plugin que estar en el directorio de plugins.
Cordova funciona en base a plugins que le van aadiendo funcionalidad a nuestro software, as
el fichero de js no crece demasiado si no es necesario.
Puedes echar un vistazo al directorio de plugins de Cordova y su compatibilidad con las
distintas plataformas mviles.
Requerimientos de software
$ cordova requirements
Necesitamos un emulador de Android. Voy a utilizar Android Virtual Device, pero Virtual
Box no permite virtualizacin anidada :-(
Evento deviceready
Lanzamos el emulador
Aadir un plugin
Vamos a modifica el fichero index.js para que muestre va consola algn dato del dispositivo:
....
receivedEvent: function(id) {
var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
Si ejecutamos nuestro proyecto de nuevo, dar un error, se pueden ver trazas mediante:
adb logcat
Compilacin
125
PhoneGap
Prctica de Cordova
Hacemos un fork de mi repositorio
Hacemos git clone del nuevo repositorio creado
Nos situamos dentro y creamos nuestro proyecto:
cd practica-cordova
cordova create futbolistas com.tunombre.futbolistas Futbolistas
rm futbolistas/www/css/index.css
rm futbolistas/www/js/index.js
cp -r sources/* futbolistas/www/
cd futbolistas/www
xdg-open index.html
Mtodo de almacenamiento
126
PhoneGap
El tpico alert de JavaScript puede ser algo rgido para tu aplicacin PhoneGap que aparenta ser
nativa. Puede ser que queramos personalizar la ventana de aviso mediante un ttulo, un texto
especfico en el botn o incluso una funcin de callback. La funcin alert de JavaScript no nos
lo va a permitir.
Para hacer una llamada a la ventana de dilogo nativa deberemos aadir el plugin
correspondiente:
<script src="cordova.js"></script>
Esta instruccin hara que Cordova inserte la versin especfica de Cordova a la plataforma en la
que estemos desarrollando en tiempo de compilacin. Es decir, el fichero cordova.js no debera
estar presente en la carpeta www de nuestro proyecto.
document.addEventListener('deviceready', function () {
if (navigator.notification) {
// Si disponemos de notificaciones nativas, sobreescribimos el alert del nav
window.alert = function (message) {
navigator.notification.alert(
message, // mensaje
null, // funcin de callback
127
PhoneGap
"Workshop", // ttulo
'OK' // Nombre botn
);
};
}
}, false);
Prueba a ejecutar la aplicacin desde el dispositivo mvil o emulador y desde el navegador del
PC. Observa que la notificacin cambia en funcin del entorno.
Esto es debido a que el navegador puede esperar en torno a 300ms por si el usuario hace un
doble clic. Para evitarlo podemos utilizar alguna librera de JavaScript como FastClick
<script src="lib/fastclick.js"></script>
FastClick.attach(document.body);
Arquitectura SPA
Vamos a configurar ahora nuestra aplicacin para que se ejecute en una sola pgina:
En el fichero index.html borramos todo el contenido del body (salvo los scripts) ya que lo
generaremos mediante JavaScript
Definiremos una funcin que ser la encargada de renderizar el home de nuestra aplicacin,
dentro de la seccin de funciones locales del script app.js:
function renderHomeView() {
var html = "<header>" +
"<h1>Futbolistas</h1>" +
"</header>" +
"<input id='btnBuscar' type='search' placeholder='Introduc
"<ul id='lstFutbolistas'></ul>"
$('body').html(html);
$('#btnBuscar').on('keyup', encontrarPorNombre);
}
128
PhoneGap
Observa que hemos quitado el botn de ayuda y que el registro del evento keyup lo metemos
dentro de la funcin renderHomeView, por lo que deberemos quitarlo de donde estaba
anteriormente (seccin registro de eventos). Tambin quitaremos el manejador del botn de
ayuda.
Modificaremos la lgica de la aplicacin, de modo que una vez que se inicialice el adaptador de
datos se muestre la vista de la pgina inicial:
adapter.inicializar().done(function () {
console.log("Inicializado: Adaptador de datos");
renderHomeView();
});
Ejemplos:
Ionic que viene preparado para funcionar con Angularjs y que se integra perfectamente
con PhoneGap
Intel App Framework que viene preparado con un css especfico para cada plataforma
mvil, para simular ms el aspecto nativo
Adobe (impulsor de PhoneGap) tambie tiene el suyo: Topcoat.
Usaremos Topcoat
Utilizaremos templates para desacoplar la definicin de la interfaz de usuario (html) del cdigo.
Si no has usado nunca handlebars, echa un vistazo a la documentacin oficial (es corta) y a un
post de ejemplo de uso de handlebars y otro post de precompilacin de handlebars.
Vamos a crear dos templates, una para la pgina de inicio y otra para mostrar los elementos de
la lista de futbolistas, que guardaremos en la carpeta templates.
Navigation bar
Search Input
List
Plantilla para la pgina de inicio (fichero templates/home.handlebars):
<div class="topcoat-navigation-bar">
<div class="topcoat-navigation-bar__item center full">
129
PhoneGap
<h1 class="topcoat-navigation-bar__title">Futbolistas</h1>
</div>
</div>
<div class="search-bar">
<input type="search" value="" placeholder="buscar" class="topcoat-search-i
</div>
<div class="topcoat-list">
<ul class="topcoat-list__container list" id="lstFutbolistas">
</ul>
</div>
{{#.}}
<li class="topcoat-list__item">
<a href="#futbolistas/{{id}}">
<img src="assets/img/{{imagen}}">
<p>{{nombre}} {{apellido}}</p>
<p>{{equipo}}</p>
<span class="chevron"></span>
</a>
</li>
{{/.}}
function renderHomeView() {
$('body').html(Handlebars.templates.home());
$('#btnBuscar').on('keyup', encontrarPorNombre);
}
function encontrarPorNombre() {
adapter.encontrarPorNombre($('#btnBuscar').val()).done(function(futboli
$("#lstFutbolistas").html(Handlebars.templates.listaJugadores(futboli
});
}
Copiamos el framework de topcoat dentro de nuestro proyecto. Podemos elegir entre un theme
claro y otro oscuro.
<script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/han
<script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/han
<script src="js/templates.js"></script>
Si probamos el resultado, vemos que se le puede dar un toque adicional de diseo. Debemos
crear un fichero style.css que aadiremos a nuestro index.html:
a {
text-decoration: none;
color: inherit;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: rgba(0, 0, 0);
}
.list {
list-style-type: none;
border-top: none !important;
}
.list > li {
position: relative;
clear: both;
padding: 0px;
margin: 0px;
}
131
PhoneGap
.chevron {
background: transparent url(../img/next_blue.svg);
background-repeat: no-repeat;
background-size: contain;
width: 20px;
height: 20px;
position: absolute;
right: 12px;
top: 22px;
}
Clase HomeView
};
//este mtodo lo movemos tal cual de app.js:
this.encontrarPorNombre = function() {
adapter.encontrarPorNombre($('#btnBuscar').val()).done(function (f
$("#lstFutbolistas").html(Handlebars.templates.listaJugadores(f
});
};
this.inicializar();
}
<script src="js/HomeView.js"></script>
adapter.inicializar().done(function () {
$('body').html(new HomeView(adapter).render());
});
Implementar scrolling
Cuando la lista de futbolistas es mayor que la ventana del navegador, si nos desplazamos, toda
la vista hace scrolling (incluido el header).
Para que el scroll se produzca solo en la lista de futbolistas crearemos una clase adicional en el
fichero assets/css/styles.css con el siguiente contenido:
.scroller {
overflow: auto;
-webkit-overflow-scrolling: touch;
position: absolute;
top: 141px;
bottom: 0px;
left: 0px;
right: 0px;
}
133
PhoneGap
Enrutado de vistas
Vamos a crear otra vista en la que mostraremos los detalles de cada jugador.
Al tener ahora nuestra aplicacin ms de una vista, habr que implementar algn mecanismo de
enrutado que determine si debemos mostrar la vista de inicio o la de detalle del jugador.
<div class="topcoat-navigation-bar">
<div class="topcoat-navigation-bar__item left quarter">
<a class="topcoat-icon-button--quiet back-button" href="#">
<span class="topcoat-icon topcoat-icon--back"></span>
</a>
</div>
<div class="topcoat-navigation-bar__item center half">
<h1 class="topcoat-navigation-bar__title">Futbolistas</h1>
</div>
</div>
<div class="detalles scroller">
<img src="assets/img/{{imagen}}" class="imagen-futbolista">
<h1>{{nombre}} {{apellido}}</h1>
<p><strong>Equipo:</strong> {{equipo}} </p>
<p><strong>Posicin: </strong>{{posicion}}</p>
<p><strong>Dorsal:</strong> {{dorsal}}</p>
<p><em>{{desc}}</em></p>
<div class="topcoat-list__container clearfix">
<ul class="topcoat-list list actions">
<li class="topcoat-list__item"><a href="tel:+34606606606"><p>L
<li class="topcoat-list__item"><a href="tel:+34606606606"><p>L
<li class="topcoat-list__item"><a href="sms:+34606606606"><p>E
<li class="topcoat-list__item"><a href="mailto:micorreo@gmail.
<li class="topcoat-list__item"><a href="#" class="add-location
<li class="topcoat-list__item"><a href="#" class="add-contact-
<li class="topcoat-list__item"><a href="#" class="change-pic-b
</ul>
</div>
</div>
this.inicializar = function() {
this.el = $('<div/>');
};
this.render = function() {
this.el.html(Handlebars.templates.jugador(futbolista));
return this.el;
};
this.inicializar();
}
<script src="js/JugadorView.js"></script>
Enrutado
Creamos una variable con la expresin regular que utilizaremos para mostrar o no la vista de un
jugador en concreto. La guardaremos en la seccin de variables locales del fichero app.js:
Definiremos un nuevo listener para cuando haya cambios en el hash de la url, dentro de la
seccin registro de eventos del fichero app.js
$(window).on('hashchange', route);
function route() {
var hash = window.location.hash;
if (!hash) {
$('body').html(new HomeView(adapter).render());
return;
}
var match = hash.match(futbolistaURL);
if (match) {
adapter.encontrarPorId(Number(match[1])).done(function(futbolista) {
$('body').html(new JugadorView(adapter, futbolista).render());
});
}
}
adapter.inicializar().done(function () {
console.log("Inicializado: Adaptador de datos");
//$('body').html(new HomeView(adapter).render());
route();
});
135
PhoneGap
.back-button {
position: absolute;
top: 10px;
}
.topcoat-icon--back {
background: url("../img/back_light.svg") no-repeat;
-webkit-background-size: cover;
-moz-background-size: cover;
background-size: cover;
}
.detalles {
margin: auto;
/*para no utilizar el top que he puesto en scroller:*/
top: 71px !important;
}
.detalles>img {
float:left;
margin:10px;
width: 250px;
height: 250px;
}
.detalles h1 {
padding: 12px 0px 4px 0px;
margin: 0px 0px 0px 0px;
font-size: 1.2rem;
}
.detalles p {
padding: 0px 0px 4px 0px;
margin: 0px 0px 0px 0px;
}
.actions > li > a {
padding-left: 12px;
}
.action-icon {
position: absolute !important;
top: 18px;
right: 20px !important;
width: 28px !important;
height: 28px;
}
.actions li p:nth-of-type(1) {
color: #5DC1FF;
font-size: 0.9em;
font-weight: lighter;
}
.actions li p:nth-of-type(2) {
color: inherit;
}
.icon-call {
136
PhoneGap
this.addLocation = function(event) {
event.preventDefault();
navigator.geolocation.getCurrentPosition(
function(position) {
alert(position.coords.latitude + ',' + position.coords.longitude);
},
function() {
alert('Error obteniendo localizacin');
137
PhoneGap
});
return false;
};
Comprobamos su funcionamiento
Aadimos el plugin:
this.addToContacts = function(event) {
event.preventDefault();
console.log('Aadiendo a Contactos');
if (!navigator.contacts) {
alert("El API de contactos no est soportada", "Error");
return;
}
/*Segn doc de Cordova: https://github.com/apache/cordova-plugin-contact
// save to device
contact.save(
function () {
alert ("Futbolista guardado en los contactos del telfono");
},
function () {
alert("uppps, no ha ido bien: " + contactError.code)
}
);
};
138
PhoneGap
Comprobamos su funcionamiento
this.cambiarFoto = function(event) {
event.preventDefault();
if (!navigator.camera) {
alert("Camera API no soportada", "Error");
return;
}
var options = { quality: 50,
destinationType: Camera.DestinationType.DATA_URL,
sourceType: 1, // 0:Photo Library, 1=Camera, 2=Sa
encodingType: 0 // 0=JPG 1=PNG
};
navigator.camera.getPicture(
function(imageData) {
$('.imagen-futbolista', this.el).attr('src', "data:image/jpeg;base
},
function() {
alert('Error al obtener la foto', 'Error');
},
options);
return false;
};
139
Web Components
Web Components
Web Components
Aprender a utilizar el framework React.js con todo lo que contiene:
Uso y configuracin bsico de webpack
Crear y usar estilos para componentes web
Enrutamiento en cliente
Utilizar componentes
140
Entorno de desarrollo mediante Webpack
Task runners
Necesitamos un compilador que nos genere el cdigo que necesita el navegador: html, css y js
(ES5)
Una SPA depende de bastantes libreras, principalmente de js.
Necesitamos concatenarlas (evitar mltiples http requests)
Consumir dependencias y gestionarlas mediante un gestor de paquetes como npm
Optimizar y comprimir imgenes
Bundlers
El problema con Grunt o Gulp viene cuando se utilizan muchos assets:
Sera til poder dividirlos en paquetes o bundlers de modo que:
Los que no se modifiquen (vendor assets), se separan, de modo que se puedan cachear
Determinadas pginas del sitio necesitan assets extra (panel de administracin)
Webpack y Browserify dan esta opcin
Ejemplo de uso
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
141
Entorno de desarrollo mediante Webpack
<title>Hola Mundo</title>
</head>
<body>
<script>
var element = document.createElement('h1');
element.innerHTML = 'Hola Mundo';
document.body.appendChild(element);
</script>
</body>
</html>
Fichero main
main.js:
'use strict';
var component = require('./component.js');
document.body.appendChild(component());
Fichero component
component.js:
'use strict';
module.exports = function () {
var element = document.createElement('h1');
element.innerHTML = 'Hola Mundo';
return element;
};
npm i webpack -g
142
Entorno de desarrollo mediante Webpack
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Hola Mundo con componentes</title>
</head>
<body>
<script src='bundle.js'></script>
</body>
</html>
Opciones de webpack
Qu hace webpack?
webpack --help
Ejemplos de uso:
webpack -w main.js bundle.js # se queda como un servicio
webpack -p main.js bundle.js # minified
webpack -d main.js bundle.js # debug con sourcemap
Configuracin de webpack
webpack tiene muchas opciones
Usaremos un fichero de configuracin para personalizarlo
Utilizamos node para montar nuestro entorno de desarrollo (plugins para webpack por
ejemplo)
Instalaremos webpack de forma local a nuestro proyecto
mkdir hola-mundo
cd hola-mundo
npm init -y
143
Entorno de desarrollo mediante Webpack
O ms corto:
npm i -D webpack
Ya tenemos el ejecutable (webpack) para poderlo utilizar. Para ver donde se instala:
npm bin
/app
main.js
component.js
/build
bundle.js (se crear mediante webpack)
index.html (a mano o mediante webpack)
package.json
webpack.config.js
un fichero esttico
un fichero generado dinmicamente
};
Ejecucin
Ejecutamos webpack:
node_modules/.bin/webpack
Configurar el build
En los scripts del fichero package.json aadimos la compilacin:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
No hace falta poner la ruta, ya que npm aade de forma temporal el directorio
node_modules/.bin al PATH.
Aadir CSS
Aadimos nuestro fichero component.css:
145
Entorno de desarrollo mediante Webpack
h1 {
color: red;
}
'use strict';
require("./component.css");
module.exports = function () {
var element = document.createElement('h1');
element.innerHTML = 'Hola Mundo';
return element;
};
Procesar CSS
Webpack debe saber importar ficheros css, para ello necesita 2 loaders:
CSS loader: que importa el fichero CSS y procesa los import y url() que tenga.
Style loader: que procesa el CSS generado por CSS Loader y lo inserta en nuestra pgina
html.
module: {
loaders: [
{ test: /\.css$/, loader: "style-loader!css-loader" }
]
}
Procesar SASS
Cambiamos nuestro fichero component.css por component.scss y con cdigo propio de Sass:
$primary-color: red;
h1 {
color: $primary-color;
}
module: {
loaders: [
{ test: /\.css$/, loader: "style-loader!css-loader" },
{ test: /\.scss$/, loader: "style-loader!css-loader!sass-loader"
146
Entorno de desarrollo mediante Webpack
]
}
npm i -S bootstrap
O mejor url-loader que nos las insertar de forma inline en funcin del peso, ahorrando
peticiones html.
Para modificar el fichero mediante Sublime es til seleccionar por columnas (ratn derecho +
Maysculas)
Mi fichero de prueba misvariables.less:
'use strict';
require("./bootstrap.less")
module.exports = function () {
var element = document.createElement('h1');
element.innerHTML = 'Hola Mundo';
147
Entorno de desarrollo mediante Webpack
return element;
};
Aadir ESLint
Instalamos ESLint en nuestro proyecto
{
"env": {
"node": true,
"browser": true
},
"globals": {
//place settings for globals here, such as
"exampleGlobalVariable": true
},
"rules": {
//enable ESLint rules, such as
"semi" : [2, "never"]
},
"plugins": [
//you can put plugins here
]
}
Configuracin de reglas
Las reglas pueden tener 3 valores:
0: Desactiva la regla
1: Genera un warning (pero el cdigo no hace un exit)
2: Genera un error y el cdigo hace un exit 1
148
Entorno de desarrollo mediante Webpack
Por ejemplo en el .eslintrc anterior el editor nos marcar como error los ; a final de linea
extend
Lo ms cmodo es utilizar eslint configurado ya por alguien, y luego hacer nuestras pequeas
modificaciones mediante rules.
Si hacemos un PR a repositorios de Airbnb, Google... deberemos ser fieles a su gua de
estilos
Utitlizaremos la gua de Airbnb porque est muy documentada:
https://www.npmjs.com/package/eslint-config-airbnb-base
La podemos modificar, por ejemplo quitando los ; al final de las lneas.
./node_modules/.bin/eslint --init
Elegimos:
"eslint-config-airbnb": "^9.0.1",
"eslint-plugin-react": "^5.1.1",
Starter kit
La configuracin de Webpack puede ser mucho ms compleja:
Nos falta poder escribir en ES6 en vez de JavaScript tradicional (transpiler babel)
Utilizaremos JSX (JavaScript XML, especfico de React)
Necesitamos editar en vivo:
Hay que configurar el plugin React Hot Loader
Lo mejor es utilizar un starter kit
Por ltimo aadiremos snippets a Sublime para poder trabajar con React ms rpido
Referencias
http://survivejs.com/webpack/introduction-to-webpack/
149
Caractersticas de ES2015
Caractersticas de ES2015
Caractersticas de ES2015
Arrow functions
Para escribir funciones de forma rpida. Esta caracterstica est presente en otros lenguajes.
Tambin se conoce como lambdas.
Ver cdigo
Ver cdigo
If you are writing JavaScript, I hope you know what "self" is and how ugly it is. We can easily avoid
it with arrow functions.
Here's a stupid example trying to console.log all the meta tags after 100 milliseconds:
Creacin de objetos
Se reduce la sintxis para la creacin de objetos:
Ver cdigo
150
Caractersticas de ES2015
Variables en cadenas
Desde ES2015 se evita la necesidad de utilizar el operador de concatenacin (+):
Ver cdigo
Tambin en multilnea:
var blogPost = `
## My First Blog Post
Ver cdigo
With this feature, you can reduce the amount of code and self-document it.
Let's say we have a user object and we are only interested in the name field. This is how we can do it
with ES2015:
var user = {name: "arunoda", address: "Colombo. Sri Lanka"}; var {name} = user;
console.log(name); This seems kind of weird at first. But its very useful when you are working on a
real app. Let's say I want to get the target of a click event. Here's how:
151
Caractersticas de ES2015
In JavaScript, we can accept any number or arguments. But this feature is kind of difficult to handle.
ES2015 makes it pretty simple.
152
Evolucin del CSS
Documentos vs Webapps
Cuando pensamos en sitios web sencillos, tenemos un pensamiento global para todas las
pginas:
Mismo header, footer, tipo de lista, prrafos...
A todas las pginas se les aplican los mismos estilos
El global scope o mbito global del CSS tiene sentido
Si nuestro sitio se vuelve complejo la cosa cambia:
El global scope y un mantenimiento fcil dejan de ser sinnimos
Es lo mismo que pasa en un lenguaje de programacin con los mbitos de las variables
.Block__Element--Modifier {....}
Ejemplo de BEM
<ul class="menu">
<li class="menu__item">
<a class="menu__link">
<span class="menu__text"></span>
</a>
</li>
</ul>
La metodologa es utilizar selectores que sean fciles de reusar, como es el selector class.
Ponemos ciertas restricciones a nuestro uso de CSS:
/* BIEN */
.alert {
font-weight: bold;
153
Evolucin del CSS
}
.danger {
color: red;
}
/* MAL, menos reusable */
.alert.danger {
font-weight: bold;
color: red;
}
Separar el contenedor del contenido (los containers no tienen que tener estilos visuales, lo que
sera el theme)
btn
btn-default, btn-primary, btn-success....
btn-lg, btn-sm, btn-xs
disable, active
Web Components
Van a llegar los web components al browser... aunque ya tiene algunos:
<select>
<option>....</option>
<option>....</option>
</select>
Situacin actual
154
Evolucin del CSS
Significa pensar en herramientas como webpack que integran imagenes y css dentro del
JavaScript:
require('./MyComponent.css')
const MyComponent = () => (
<div className='MyComponent'>
<div className='MyComponent__Title'>....</div>
...
</div>
</div>
);
export default MyComponent
Cuando queremos usar el componente todos sus assets nos dan igual:
Server render CSS: hay que extraer el CSS que genera el JS mediante algn plugin de webpack
ver: http://stackoverflow.com/questions/34615898/react-server-side-rendering-of-css-modules
:hover, :focus, :active
Media queries
Prefijos por navegador
Soluciones
CSS Modules
No queremos hacer CSS con JavaScript
...
</div>
</div>
);
export default MyComponent
Fichero css:
Composicin:
.foo {
composes: heading from '/typography.css';
composes: box from 'layout.css';
color: red;
}
Radium
ReactCSSTransitionGroup -> Minuto 31
156
Reactjs
Reactjs
React.js
Desarrollado por facebook y utilizado en su sitio web
Quin usa React?
Instagram est realizado completamente con React
Airbnb
Uber
Netflix
....
Sirve para simplificar el diseo de interfaces de usuario complejas
Requisitos
JavaScript
npm
ES2015
Componentes
React se basa en componentes
Utilizaremos clases de JavaScript (ES2015)
Si un componente es complejo se divide en componentes ms simples
Cada componente es como una funcin:
Genera una salida cuando se ejecuta: mtodo render()
La ejecucin se produce sobre un dom virtual
Virtual Dom
Permite que React sea muy rpido
React utiliza el DOM Virtual para hacer los mnimos cambios posibles en el DOM real
La renderizacin en el navegador es mucho ms rpida
Se ejecuta un diff entre el dom virtual y el dom real y se actualizan solo las diferencias.
Primeros pasos
Aunque no es lo habitual en los tutoriales de React:
Hola Mundo
157
Reactjs
JSX
JSX = JavaScript XML
Todo lo que devuelve el mtodo render se escribe en JSX
Conseguimos cdigo html legible (sin comillas) dentro de js
Mezclamos JavaScript con html?
... y dentro de poco tambin CSS
Si, no pasa nada: es un componente web
Mezclamos todo?
render debe devolver un nico elemento html
El atributo class de html es una palabra reservada de JavaScript, por lo que en JSX se utiliza
className
Las variables en JSX se ponen mediante llaves
Funcion map
Es bastante habitual utilizar la funcin map cuando manejamos arrays:
158
Reactjs
</div>
);
}
}
Ejercicio:
Cmo implementaras el mtodo render si adems de los famosos tuvieras que mostrar sus
comentarios?
Utiliza como ejemplo este array de objetos:
var comentarios= [
{autor: 'Oliver Khan', frase: 'Ultimamente veo ms los abdominales de Cristi
{autor: 'Albert Einstein', frase: 'Dos cosas son infinitas: el universo y la
]
Solucin:
npm i -D json-loader
module.exports = {
...
module: {
loaders: [
{ test: /\.json$/, loader: "json-loader" }
]
}
}
159
Reactjs
Por ltimo, descargamos nuestro json de las cervezas, en el mismo directorio que el
componente App:
wget https://raw.githubusercontent.com/juanda99/proyecto_web_basica/master/cer
Cada elemento del DOM virtual puede corresponder a un elemento del DOM real y la forma de
conseguir la trazabilidad es mediante la propiedad key.
Intentemos ahora hacer una cosa en la que React es muy bueno: simplificando cdigo, haciendo
las cosas sencillas. Ahora mismo nuestro cdigo tiene dos pegas:
Nuestra clase App define la renderizacin de las cervezas:
Debera indicar que hay que renderizar cervezas
Otra clase llamada Cerveza debera ser la que tuviera los detalles de como
renderizarlas.
El cdigo se ve algo complejo, quiz mejore al crear la clase Cerveza, pero podis pensar
adems que se mezcla el cdigo js con el cdigo en html de forma que queda poco
legible.
Pensando en componentes, ahora mi class App representa una lista de cervezas. La renderizacin de
cada cerveza puede ser muy simple o muy compleja. Quiz nos interese tener una clase especfica
para representarla:
160
Reactjs
}
}
static propTypes = {
marca: PropTypes.string,
envase: PropTypes.string,
key: PropTypes.string
}
161
Reactjs
intrnsecos al componente y no dependen de componentes superiores (si no, los pasaramos por
propiedades). Hay que tener en cuenta 3 cosas:
Siguiendo con el ejemplo anterior, vamos a recibir tambin la descripcin de la cerveza de forma que
habitilitaremos un botn en cada componente Cerveza para mostrar o no la descripcin de la misma.
handleClick(){
this.setState({mostrarDescripcion: !this.state.mostrarDescripcion})
}
render() {
var {key, marca, envase, desc} = this.props
var descripcion = this.state.mostrarDescripcion ? <textarea>{desc}</textar
var textoBoton = this.state.mostrarDescripcion ? 'Quitar descripcin': 'Mo
return (
<div id={key}>
<h1>Marca:{marca}</h1>
<button onClick={this.handleClick}>{textoBoton}</button>
<p>Envasado: {envase}</p>
{descripcion}
</div>
)
}
}
Es importante ver que el pulsar sobre el botn no tiene un efecto directo sobre el dom (virtual), sino
sobre el estado del elemento. El cambio del estado hace que se renderice todo el elemento y que
entonces cambien tanto el texto del botn como la visibilidad del textarea. Esto hace que el cdigo en
react sea ms legible y fcil de manetener que por ejemplo en jQuery.
Ajax
162
Reactjs
Mtodos en React
constructor()
componentWillMount()
render()
componentDidMount()
componentWillUnmount()
obtenerCervezas() {
var that = this
var misCervezas = fetch('http://localhost:8080/api/cervezas')
misCervezas.then(function(response) {
return response.json()
}).then(function(data) {
console.log('parsed json', data)
that.setState({
cervezas: data
})
}).catch(function(cervezas) {
console.log('parsing failed', cervezas)
})
}
constructor(props) {
super(props)
this.state = {
cervezas: []
}
}
componentDidMount() {
this.obtenerCervezas()
}
render() {
163
Reactjs
Actualizaciones
componentDidMount() {
this.timer = setInterval(() => this.obtenerCervezas(), 10000)
}
componentWillUnmount(){
clearInterval(this.timer)
}
164
Real Time
Real Time
Real Time
Qu es real time?
La pregunta podramos hacerla de otra forma... cundo un usuario tiene la sensacin de que cuando
utiliza una aplicacin esta le responde con informacin en tiempo real?
Esto puede ser relativo al tipo de aplicacin: no es lo mismo una reserva de avin o de autobs que
una compra en bolsa. Sin embargo tampoco es lo mismo una compra en bolsa para usuarios que
operan en intrada y usuarios que lo hacen en largo plazo. Su concepto de tiempo real difiere
enormemente.
Long Polling
Short Polling
Suscripciones
http://stackoverflow.com/questions/4642598/short-polling-vs-long-polling-for-real-time-web-
applications
http://stackoverflow.com/questions/10028770/html5-websocket-vs-long-polling-vs-ajax-vs-webrtc-
vs-server-sent-events
165
Proyectos solucionados
Proyectos solucionados
Prcticas solucionadas
A continuacin se presentan las cuatro prcticas solucionadas. Estn tambin colgadas en los
repositorios de GitHub correspondientes, bajo la rama de Soluciones.
166
Proyecto Web bsica
cd
git clone <url>
cd proyecto_web_basica
subl .
Esqueleto html5:
! + tab
link + tab
header+aside+main+footer
167
Proyecto Web bsica
div*2>(h1.bannerTitle+div.bannerBody>p*2>lorem)
Completa el men y si todo est correcto, es el momento de clonar el contenido hecho hasta
ahora al resto de ficheros del sitio web (ficheros cervezas.html y contactar.html). Puedes
hacerlo desde Sublime Text instalando el plugin SideBarEnhancements
Pulsa CTRL + MAYS + H para formatear el cdigo desde Sublime Text (plugin HTML
Prettyfy)
Comprueba que el cdigo html5 sea vlido, ya sea va web o mediante plugin del editor de
cdigo (plugin w3cvalidators). Si te da algn warning por mltiples h1 no es importante.
Sera un buen momento para tener nuestra primera instantnea de nuestro trabajo. Realiza
primero una validacin del cdigo html
git status
git add -A
git commit -m "Generada estructura y cdigo base"
git push
index.html
<main>
<article>
<header>
<h1 class="newstitle"><a href="">Como se tira la cerveza</a></
<p class="newsdate">17 de Mayo de 2016</p>
</header>
<p>Quienes ms saben de esto recomiendan la tirada especial o en d
<p>El primer tiempo consiste en llenar tres cuartas partes de la c
<p>Los expertos consideran que algunas modas, como las de congelar
</article>
<article>
<header>
<h1 class="newstitle"><a href="">El consumo moderado de cervez
<p class="newsdate">14 de Mayo de 2016</p>
</header>
<p>El informe fue presentado por el centro Cerveza y Salud con la
<p>Varios componentes de la cerveza: la fibra soluble, los compues
</article>
</main>
Comprueba el document outline del documento. Puedes utilizar la extensin HTML5 Outliner
168
Proyecto Web bsica
git status
git add <ruta/index.html>
git commit -m "rellenado cdigo del main"
git push
cervezas.html
Es una tarea similar al caso anterior, sin embargo lo primero que debemos hacer es dejar
nuestro fichero json como un texto plano que ser lo que envolveremos luego en nuestras tags
de html.
Obtener multicursor a principio de todas las lnas: seleccionando por columna (botn derecho y
maysculas).
contacto.html
<h1>Contactar</h1>
<p>No me interesa conocerte. Si sabes de alguna cerveza que merezca la pen
<p>Quiz me anime y la ponga en la lista!</p>
<form action="contactar.php">
<div>
<label for="cerveza">Nombre</label>
<input type="text" name="cerveza" id="cerveza">
</div>
<div>
<label>Descripcin</label>
<textarea name="desc" id="desc" cols="30" rows="10"></textarea>
</div>
<div>
<input type="submit" value="Enviar">
</div>
</form>
169
Proyecto Web bsica
CSS general
header, footer {
background-color: orange;
}
En principio es mejor no dar altura a header o footer. No queremos dar lmites que hagan que
los elementos se salgan de su contenedor.
El color de fondo no se pinta en todo el ancho, por culpa del margen del body, as que aadimos
la libera normalize que se encarga de estndarizar ciertos valores comunes en todos los
navegadores:
Para aadir las libreras lo mejor es utilizar el plugin cdnjs con la opcin cdnjs: search (o
pulsando botn derecho)
.logo{
width: 60px;
height: auto;
margin: 5px;
float: left;
}
header, footer {
background-color: orange;
overflow:hidden;
}
El men queremos que quede horizontal. Utilizamos la propiedad inline-block para el display
porque queremos separar los elementos del men. Qu pasa si pones inline? El navegador te
entiende? Es el momento de instalar si no lo tienes todava, un linter para css...
.menuitem {
display: inline-block;
margin: 5px;
}
.menulink {
text-decoration: none;
}
.menulink:hover {
color: white;
}
170
Proyecto Web bsica
Si ahora queremos colocar el men a la altura de la foto, tendremos que transformar elementos
con un display de tipo bloque (h1 o p y nav en elementos flotantes, de modo que puedan
coexistir en la misma altura):
nav {
float: right;
}
.subtitle {
float:left;
}
header {
overflow: hidden;
}
Quitamos mrgenes en el ttulo para que quede mejor y ajustamos tambin el footer:
.title {
margin-bottom: 0;
}
.subtitle {
margin-top: 0;
float:left;
}
.copyright {
text-align: center
}
CSS responsive
ViewPort
No podemos trabajar con containers de tamao fijo a no ser que haya unas media queries
previas. La anchura de la pgina web la deben marcar las caractersticas del navegador cliente.
Lo primero es configurar el view port:
meta:vp + tab
<meta name="viewport" content="width=device-width, initial-scale=1">
Menu responsive
171
Proyecto Web bsica
<nav>
<button onclick="toggle_visibility('menu');" class="btnmenu">Menu</but
<ul id="menu" class="menu">
...
El botn har que se muestre o no el men. Esa interaccin con el usuario, debe hacerse con
JavaScript:
<script type="text/javascript">
function toggle_visibility(id) {
var e = document.getElementById(id);
if(e.style.display == 'block')
e.style.display = 'none';
else
e.style.display = 'block';
}
</script>
En principio el botn, el men, o el subttulo estarn visibles o no, en funcin de media queries:
Anchura de la pgina
.container {
margin: 0 5px;
}
@media screen and (min-width:701px) {
.container {
width: 690px;
margin: 0 auto;
}
}
172
Proyecto Web bsica
Nuestro cdido se empieza a complicar, quiz sera buena idea ir creando stylesheets
especficas
Para situar los banners a dos columnas optaremos por hacerlo a partir de 1001px. El cdigo del
fichero medium.css quedar as:
.container {
width: 990px;
overflow: auto;
}
aside {
float: left;
width: 20%;
}
main {
float: left;
width: 80%;
}
Plantillas
npm i -g handlebars
handlebars templates/ -f js/templates.js
En nuestros ficheros html habr que cargar, tanto las plantillas como el js que las lea:
173
Proyecto Web bsica
<script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handl
<script src="js/templates.js"></script>
<div id="header"></div>
Y por ltimo ejecutamos un script dentro de nuestro html que cargue la plantilla del header en
la etiqueta #header anterior:
<script>
document.getElementById("header").innerHTML = Handlebars.templates.hea
</script>
Fuentes?
Uso de Google Fonts
Usar rem y probar funcionamiento
174
Web con bootstrap y gulp
Creo mi aplicacin
mkdir proyecto
cd proyecto
yo webapp
Seleccionaremos Sass, Bootstrap y Modernizr. No haremos test, as que da igual BDD que
TDD.
Eliminamos el body del fichero app/index.html con cuidado de no borrar las llamadas a las
hojas de estilos y js, ni los comentarios previos ni posteriores
$icon-font-path: '../fonts/';
// bower:scss
@import "bower_components/bootstrap-sass/assets/stylesheets/_bootstrap.scss";
// endbower
Servidor web
Para empezar a trabajar modificando cdigo, lo mejor es levantar un servidor web:
gulp serve
Pgina de contactar
Aadimos un men responsive en la parte de arriba de la pgina
bs3-navbar-responsive + tab
175
Web con bootstrap y gulp
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse navbar-ex1-collapse">
<ul class="nav navbar-nav navbar-right">
<li class="active"><a href="#">Inicio</a></li>
<li><a href="#">Mis cervezas</a></li>
<li><a href="#">Contactar</a></li>
</ul>
He aadido un formulario al body, los comandos que he utilizado son los siguientes:
bs3-input:text:h + tab
bs3-input:email:h + tab
bs3-input:submit:h + tab
Para que quede bien aadimos un container para el body (container o container-fluid) que
englobe al formulario (MAYS + CTRL + g en emmet, y escribimos .container).
body {
padding-top: 70px;
}
$icon-font-path: '../fonts/';
176
Web con bootstrap y gulp
// bower:scss
@import "_theme.scss";
// endbower
body {
padding-top: 70px;
}
Para cambiar el estilo de boostrap, lo mejor, en la medida de lo posible es utilizar sus variables:
Es el modo que han definido los creadores para hacer las modificaciones de forma
sencilla.
Observa que tambin podras hacer las modificaciones va web, pero sera ms costoso:
No siempre tienes claros los cambios
Hay pginas que te dejan ver los cambios en vivo mejorando la pgina
"Customize" del propio bootstrap.
Ejemplo de uso
Comprobamos que efectivamente es el encargado, viendo el css que hay definido en el mixin
button-size:
// Button sizes
@mixin button-size($padding-vertical, $padding-horizontal, $font-size, $line-h
padding: $padding-vertical $padding-horizontal;
font-size: $font-size;
line-height: $line-height;
border-radius: $border-radius;
}
Aadir plugins
Vamos a buscar un plugin para hacer una validacin ms especfica:
Le podremos dar el css que nosotros quereamos, sin ser algo especfico del
navegador
Tendr mtodos adicionales para la validacin (adems de los que podamos definir
nosotros).
gulp wiredep
En nuestro fichero main.js aadimos el cdigo necesario para cargar nuestro plugin con nuestro
formulario (al formulario le he aadido el id frmcontactar):
$('#frmcontactar').validate();
178
React.js con material-ui
npm install
npm i -S react-router
El cdigo que a continuacin utilizaremos est formateado sin acabar en ";". Por ello:
node_modules/.bin/eslint --fix .
179
React.js con material-ui
Vamos a intentar hacer ahora rutas anidadas. En la ruta base, cargaremos una plantilla que ser
la encargada de colocar el men, header y footer para todas las pginas:
Creo una carpeta llamada layout donde colocaremos el footer, header y resto de componentes
asociados a la plantilla. De momento la plantilla con el siguiente cdigo:
Lo primero que debemos hacer es instalar y configurar material-ui para el uso en nuestra
aplicacin:
En el fichero app.js:
En el index.html:
<link href='https://fonts.googleapis.com/css?family=Roboto:400,300,500' re
Comprobamos si funciona o no, mediante un npm start y vemos que los warnings que nos han
salido en la instalacin hay que arreglarlos: ciertos errores de dependencias que nos obligan a
actualizar la versin de react y react-dom
constructor(props) {
super(props);
this.state = {open: false};
}
render() {
return (
<div>
<RaisedButton
label="Toggle Drawer"
onTouchTap={this.handleToggle}
/>
<Drawer open={this.state.open}>
<MenuItem>Menu Item</MenuItem>
<MenuItem>Menu Item 2</MenuItem>
</Drawer>
</div>
)
}
}
181
React.js con material-ui
Comprobamos que no funciona ya que para usar los componentes de Material-ui es necesario
utilizar un theme. Lo aadimos tal y como marca la documentacin, en el fichero App.js:
182
React.js con material-ui
)
}
}
Si lo ejecutamos ahora veremos que funciona. Sin embargo el botn queda escondido detrs del
men. Lo podemos arreglar utilizando css directamente desde el JavaScript:
const styles = {
container: {
width:'800px',
margin: '0 auto'
}
}
constructor(props) {
super(props);
this.state = {open: false};
}
render() {
return (
<div style={styles.container}>
<RaisedButton
label="Toggle Drawer"
onTouchTap={this.handleToggle}
/>
<Drawer open={this.state.open}>
<MenuItem>Menu Item</MenuItem>
<MenuItem>Menu Item 2</MenuItem>
</Drawer>
</div>
)
}
}
Ms tareas
Podramos aadir otros componentes pero la tarea no deja de ser similar.
Quiz podramos utilizar un sistema de rejilla tipo Bootstrap para colocar los elementos y
ahorrarnos cdigo css o js. Una buena opcin sera http://flexboxgrid.com/.
183
React.js con material-ui
184