De dónde venimos
Pre-2004
- Html plano
- Plantillas renderizadas en servidor (java, asp, algo de php..)
- AJAX? WTF?
- El server manda en TODO
YUI, Prototype & Dojo Toolkit
2004 - 2006
- Plantillas renderizadas en servidor (java, php)
- Interacción "rica" en cliente, vía javascript
- Primeros intentos de 'domar' la prog. cliente (dojo)
- Complicado de la hostia, incompatibilidades entre browsers
jQuery
2006 - 2010
- Estandarización entre browsers
- Eliminación de diferencias entre browsers
- Consistencia entre browsers
- Un sólo desarrollo para diferentes browsers
- La programación en cliente como programación, no como puzzle
- Sistema de plugins FÁCIL + componentes interfaz estandar
Backbone, Spine, Ember, Angular, Coffeescript, Batman, blahblahblah
2011+
- Incorporación de gente de servidor (AKA: Gente que sabe programar)
- Aplicación de paradigmas de servidor al cliente
- MVC, MVVM, etc
- Lógica de presentación en cliente
- Thick Client (cliente pesado)
- AMD
Anatomía de una webapp actual
Templates
Plantillas renderizadas y refrescadas desde cliente. Propuestas por primera vez (hasta donde yo sé) por John Resig en http://ejohn.org/blog/javascript-micro-templating/.
Logiless
Mustache, Handlebars, Hogan
Logicfull
Underscore, dot, ejs
Aspecto de una plantilla
Handlebars
<div class="entry">
<h1>{{title}}</h1>
<div class="body">
{{body}}
</div>
</div>
Underscore
<div class="entry">
<h1><%= title %></h1>
<div class="body">
<% print(body.toLowercase()) %>
</div>
</div>
Presentación y animaciones
CSS3
- Animaciones
- Menús
- Transiciones
- MAGIA
MVC vs MVVM
MVC
- Model - View - Controller
- Separación entre datos y presentación
- Más fácil para gente de back, más limpio
- Backbone, Spine, Ember
MVVM
- Model - View - Viewmodel
- Datos y presentación unidos
- Más fácil para gente de front
- Angular, Knockout
Qué es backbone?
Backbone es un framework MVC muy muy ligero (1500 lineas de código en total).
Proporciona:
- Una abstracción de la capa de persistencia de datos (una API rest)
- Un sistema de gestión de rutas
- Un sistema de herencia de clases (para modelos y controladores)
- Una estructura estandar (models (modelos), views (controllers), vistas (el sistema de plantillas que quiera el usuario))
Qué NO es backbone?
Para todo lo demás, Backbone es no-opionated. Es agnóstico a que sistema de plantillas se utilize, a que se use para hacer el data binding, testing, etc.
Las únicas dependencias 'duras' de backbone son jquery/zepto y underscore (y json2 si se quiere compatibilidad con Satán (ie < 9))
Ventajas y desventajas del un-opinionantismo
- + Da mucha flexibilidad al usuario y no te impone como hacer las cosas
- - Obliga a tomar decisiones desde el principio, por lo que los primeros pasos pueden ser más duros
- + Mucho más adaptable al proyecto
- - Necesidad de mucho boilerplate
MVC en backbone
(L)User
↑ OutputInput↓
View (Templates)
↑ .html()DOM events↓
Controllers (Backbone.View)
↑ model eventsmodel methods↓
Models (Backbone.Model)
↑ AJAX ↓
Data persistence ⛁ (API REST)
Modelos
Modelan un recurso. Normalmente se "suscriben" (vía .url) a un punto de entrada de una API rest y consumen y persisten los datos a través de ese entry point.
Propiedades importantes
- .url / .url()
- .get() / .set() (siempre!)
- .toJSON()
- .defaults (cuidado!)
- .fetch() -> GET
- .save() -> POST o PUT
- .destroy() -> DELETE
- .validate()
Un modelo de backbone
var userModel = Backbone.Model.extend({
defaults: {
name: '',
age: 0
},
initialize: function(params) {
this.friends = [] // importante hacer esto así!
},
url: 'http://example.com/user/'
})
Colecciones
Arrays de modelos con cierta funcionalidad propia
- .url -> Recurso que devuelve un array de datos
- .model -> Model de backbone al que castea los datos
- .fetch / .toJSON / etc
- No ofrece paginación (maaaaaal)
Controller (Backbone.View)
Enlaza los datos (modelo) con lo que ve el usuario (temmplates). Escucha eventos en ambos sitios y lanza las acciones adecuadas cuando se producen
Propiedades importantes
- .el -> nodo jQuery del DOM dónde se pintará la vista asociada
- .render() -> Método que lanza el pintado de la vista en el DOM
- .events -> Diccionario con las acciones que se lanzan cuando se producen eventos en el DOM
- .model -> Instancia de un model asociada a la vista
Un ejemplo de controller
var userProfileController = Backbone.View.extend({
events: {
"click .save": "saveUser",
"change .name": "updateName"
},
template: 'http://example.com/userProfile.html',
initialize: function() {
this.model.on('change', this.render.bind(this));
this.model.fetch();
},
saveUser: function() {
this.model.save();
},
updateName: function() {
var userName = this.$('.name').val();
this.model.set('name', userName);
},
render: function() {
var userData = this.model.toJSON();
var view = _.template(this.template, userData);
this.$el.html(view)
}
})
Routers
Escuchan los cambios en el hash de la url y ejecutan acciones en función de ellos. También pueden usarse con urls completas, usando Push State.
Backbone.history.start() pone a backbone a escuchar los cambios en la url
Un ejemplo de Router
var routes = Backbone.Router.extend({
routes: {
"!/userProfile/:id": "showUserProfile"
// http://example.com/#!/userProfile
},
showUserProfile: function(id) {
var userModel = new userModel({id: id});
var userController = new userProfileController({
el: $('.profile'),
model: userModel
})
}
})
Backbone.history.start()
Boilerplate
(AKA: Cosas que hay que escribir en cada proyecto)
- Data Binding
- Carga de Templates & estáticos
- Parent inheritance
- Gestión de memoria en binds a modelos
En principio, Marionette dará algunas de estas cosas resueltas, el resto están ya resueltas en sonata Retail