El equipo es pequeño, los recursos son limitados, llevamos como 2 años de retraso y nuestras habilidades de front dejan mucho que desear. La cuenta de resultados de la empresa está en negativo y hay que rehacer todo desde cero. Empezamos con el backend y avanzamos a buen ritmo (teniendo en cuenta que apenas tenemos experiencia en rails). Pero el front es un problema... Todo ese jquery está creciendo sin control, se nos está yendo de las manos y la interfaz es muy compleja. ¿Y no habrá algo por ahí de frontend que nos de algo parecido a lo que ruby on rails nos está dando en el backend: máxima productividad?
Así es cómo, a mediados de 2013, conocí AngularJS. En esta charla os contare qué cosas hemos aprendido estos dos años, qué podríamos mejorar, qué hemos hecho bien, qué "cagadas mínimas tolerables" hemos asumido (y otras menos tolerables), qué nos ha ayudado y qué no. En resumen: cómo y porqué angular ha sido una herramienta clave que nos ha permitido darle la vuelta a la cuenta de resultados.
8. DAY 01: lo que funcionó
• El backend (hecho con rails)
• Bootstrap
9. DAY 01: lo que no
funcionó
• Usabilidad de la aplicación de gestión
• Formularios con bastantes campos y validaciones
complejas
• Muchas relaciones
• Código javascript escrito en jQuery se hace complicado
de mantener
(posiblemente el problema lo tenía yo, no jQuery)
• Consumir drogas: intentar implementar una arquitectura
hexagonal
10. DAY 01: junio 2013
• Lecciones aprendidas
• Rails fue muy buena opción
• Ni papa de frontend
• jQuery: muy bien para algunas cosas, va a ser
complicado para otras
• Vamos a tener una interfaz compleja porque
vamos a tener flujos de trabajo complejos
11. DAY 01: el problema con
jQuery / Interfaz compleja
¿y no habrá un rails para Javascript?
12. DAY 01: el problema con
jQuery
https://twitter.com/glebm
Introducción a angularJs
Verano 2013
Me decanto por angularJS
13. DAY 01: agosto 2013
Empezamos el desarrollo del nuevo extremadura.com
15. DAY 01: Las decisiones
• Seguir con rails
• Usar mongodb
• Seguir con Bootstrap y con jQuery
• Arquitectura de microservicios (otro ejemplo de
que las drogas son muy malas)
• No utilizar ayuda externa
16. DAY 01: Las decisiones
Impulsado por el CEO
Hacer un desarrollo basado en hitos cortos
19. DAY 90: introduzco
AngularJS en el stack
• ¿por donde empiezo?
• Me suscribo a egghead.io y me veo todos los
vídeos
• Me compro el ng-book
• Empiezo a asistir a las reuniones de este
meetup (primera reunión fue el 2 de diciembre
de 2013)
20. DAY 90: introduzco
AngularJS en el stack
• ¿Por donde empiezo?
• todavía me empeño en tomar drogas: intento empezar con el
muro
• Con ayuda del CEO vuelvo a los hitos cortos: desarrollo de
componentes sencillas
• Selector de fechas para un evento
• Directiva para incluir un editor WYSIWYG
• Sistema de comentarios
• Botón de me gusta
21.
22. DAY 90: introduzco
AngularJS en el stack
• Por los requisitos SEO, toda la parte de frontend
se desarrolla como una aplicación web
tradicional (no SPA)
• El back office se desarrolla como una SPA
• Mucha presión para entregar todo para ayer
23. DAY 90: introduzco
AngularJS en el stack
• Se estructura el código en carpetas
• controladores
• servicios
• directivas
• Se introducen muchas dependencias: ngTable,
ngCUALQUIER-COSA-PARA-IR-RAPIDO
• Se parte la aplicación en muchas aplicaciones: fotos, vídeos,
eventos, redacción, etc…
• Se usan eventos para comunicar directivas entre sí
24. DAY 90: introduzco
AngularJS en el stack
• No hay dinero en la caja y tengo poca experiencia así que…
• Copy&Paste de código
• El digest cycle y las ñapas para solventarlo sin saber lo que está
pasando
• usamos el ControllerAs syntax porque egghead lo recomienda
pero sin entender muy bien porqué
• Poco uso de ngModelController, muchos $watch
• Uso de $emit y $broadcast
• No se hace testing
25. DAY 180-455
• Adquiero el mínimo conocimiento suficiente (25%) que
me permite hacer el 80% de lo que necesito… por
supuesto todo para ayer
26. DAY 180-455
• angular-rails-resource: CRUD en cuatro líneas
factory(‘MediaPhoto',['railsResourceFactory','railsSerializer','MediaPhotoCollectionsPaginated',
function(railsResourceFactory,railsSerializer, MediaPhotoCollectionsPaginated){
var baseUrl = ‘/path/to/the/resource‘;
var resource = railsResourceFactory({
url: baseUrl,
name: 'media_photo'
});
resource.include({
getMediaCollections: function(query){
return MediaPhotoCollectionsPaginated.query(query,{id: this.id});
}
});
return resource;
}])
29. DAY 180-455
• Separación de plantillas en ficheros
independientes
• …muchas peticiones adicionales
• …son ficheros estáticos muy pequeños
• …nuestro volumen de tráfico nos lo permite
31. DAY 455: El cambio
• Me leo el libro build your own angular (sólo 6 capítulos)
• Entiendo el digest cycle y el double binding, dejo de tener
problemas a la hora de usar jquery y un montón de cosas
más
• Entiendo qué es el scope y el porqué de ControllerAs syntax
• Entiendo cómo se parsean las expresiones en angular: por
fin entiendo los “callbacks” de las directivas
• Empiezo a entender ngModel y NgModelController y a usarlo
en mis directivas
32. DAY 455: El cambio
• Directivas anidadas: me creo mi propias directiva
de tablas, aunque todavía no encapsulo el glue
code. Me inspiro en el ngTable y el ui.bootstrap
• Uso callback para evitar $watch en la medida de
lo posible: creamos muchos onSelect, onDelete,
onBlablabla
• Empiezo a reducir dependencias: soy capaz de
hacer más cosas
34. DAY 573: Angular con estilo
http://www.meetup.com/AngularJS_Madrid/events/222475163/
https://github.com/johnpapa/angular-styleguide
35. DAY 573: Angular con estilo
• Uso de controllerAs y bindToController en todas
las directivas
• Empiezo a hacer componentes realmente
reutilizables encapsulando también el glue code
a través de servicios
38. Angular Sucks
• Rendimiento
• Scope inheritance
• Curva de aprendizaje
• Es matar moscas a cañonazos
• Estructuración del proyecto demasiado abierta
• Las dependencias son un infierno
39. Angular Sucks
• Rendimiento: podemos limitarnos a un número de elementos en
pantalla que no sena un problema. En este momento no
necesitamos 60 fps.
• Scope inheritance: no se usa, sólo usamos isolated scopes
• Curva de aprendizaje: nada es gratis
• Es matar moscas a cañonazos: no estamos matando moscas,
estamos derribando un escuadrón de cazas de combate y sólo
tenemos una batería antiaérea
• Estructuración del proyecto demasiado abierta: convenios
• Dependencias: …sí, lo cierto es que son un infierno
40. Angular nos ha permitido
• Mejorar la usabilidad de nuestra aplicación de gestión
• Desarrollar formularios complejos, embebiendo y reutilizando
lógica de negocio en diferentes sitios
• Reutilizar códigos través de directivas, reduciendo los tiempos de
desarrollo
• No tener que ampliar el equipo de desarrollo, cosa que no
podíamos hacer
• Sistema de routing (ui.router), plantillas, peticiones HTTP, lógica
de negocio, validación, componentes reutilizables… todo
integrado
41. DAY 01: lo que funcionó
• El backend (hecho con rails)
• Bootstrap
42. TODAY: lo que funcionó
• El stack Rails/Bootstrap/angularJs
• Leer/estudiar/investigar con efectividad
• Hitos cortos, alcanzables y medibles
• Hablar con la gente de tus miserias y tus cagadas
• Participar en los meetups, no sólo escuchando
sino contando tu historia. Siempre puede ayudar a
alguien
43. ¿qué hacemos diferente
hoy?
• No tomar drogas: hitos pequeños, alcanzables y medibles
• Se ha reducido la presión (ya no tiene que estar todo para ayer) lo que te
deja tiempo para pensar
• Leer y aplicar la guía de John Papa: https://github.com/johnpapa/angular-
styleguide
• Organizar bien la estructura de ficheros del proyecto desde el primer día
• Tener mucho cuidado con meter paquetes de terceros. A veces una
directiva muy sencilla te ahorra un montón de problemas
• Emplear tiempo en entender cómo funciona el digest cycle
• Aprender bien los detalles de directivas y servicios
44. …y todo esto
¿no lo podías haber
logrado con
(ember | flux | …) ?
45. …con todo esto
¿es angular una
herramienta productiva?
Mi juicio es que sí lo es
¿Alguna pregunta?
@aalbagarcia
alfonso@extremadura.com
Notes de l'éditeur
Esta historia comienza en marzo de 2013.
La empresa está muy mal… muy muy mal. Caída de facturación, pérdida de clientes, producto obsoleto.
En ese momento surge una oportunidad de hacer un proyecto que se llama “el grito del emprendedor”
Node: fui a spainjs para que ver qué me podían contar sobre node.
Enseñar el fichero app/assets/javascript/extcom_app/directives.js, app/assets/javascript/extcom_app/controllers.js
Enseñar app/admin/views/albums. La app de eventos se hizo igual, se convirtió en algo intratable.
Enseñar la app/assets/javascript/extcom_app/albums
No se hace testing porque:
- eso de tener que preparar todas las peticiones lleva demasiado tiempo
- poca lógica de negocio implementada a nivel de cliente
Esto es más feo que el copón pero:
Aguanta una persona de 90 KG
Se desliza por la pista magnética
Se puede mostrar el código de app/assets/javascripts/extcom_app/directives/table* Indicar que eso hay que cambiarlo.
Para el ejemplo del onSelect etc mostrar la directiva app/assets/javascripts/extcom_app/posts/posts/directives/forms/post_form.js
Para el primer punto se puede enseñar la directiva media/directives/photos/entity_collections.js
Mostrar el segundo punto con el mediaPhotosUploaderService que está en app/assets/javascripts/extcom_app/media/photos/directives/media_photos_uploader.js