SlideShare a Scribd company logo
1 of 45
Download to read offline
Introducción a Backbone.js
Sergio Espín¿Cómo de sexy puede hacer
Backbone mi código?
Sergio Espín
@bytespin
¿Qué es Backbone?
● Librería JavaScript muy ligera para desarrollo de aplicaciones web
● Ofrece:
● Estructura de datos: Modelos y Colecciones
● Interfaz: Vistas y Rutas
● MVC
● RESTful
¿Qué es Backbone?
● Librería JavaScript muy ligera para desarrollo de aplicaciones web
● Ofrece:
● Estructura de datos: Modelos y Colecciones
● Interfaz: Vistas y Rutas
● MV*
● RESTful
Dependencias
● Jquery
● Underscore
●
Backbone
Dependencias
●
Modelo
Modelo
var Todo = Backbone.Model.extend({});
var todo1 = new Todo();
console.log(JSON.stringify(todo1));
// Logs: {}
var todo2 = new Todo({
title: 'Check the attributes of both model instances in the
console.',
completed: true
});
console.log(JSON.stringify(todo2));
// Logs: {"title":"Check the attributes of both model instances in the
console.","completed":true}
Inicialización
var Todo = Backbone.Model.extend({
initialize: function(){
console.log('This model has been initialized.');
}
});
var myTodo = new Todo();
// Logs: This model has been initialized.
Modelo
Valores por defecto
var Todo = Backbone.Model.extend({
defaults: {
title: '',
completed: false
}
});
var todo2 = new Todo({
title: 'Check attributes of the logged models in the console.'
});
console.log(JSON.stringify(todo2));
// Logs: {"title":"Check attributes of the logged models in the
console.","completed":false}
Modelo
Get, set y toJSON
● Get
console.log(todo1.get('completed')); // false
● Set
myTodo.set("title", "Title attribute set through
Model.set().");
myTodo.set({
title: "Both attributes set through Model.set().",
completed: true
});
● ToJSON
var todo1Attributes = todo1.toJSON();
console.log(todo1Attributes);
// Logs: {"title":"","completed":false}
Modelo
Cambios en el modelo
var Todo = Backbone.Model.extend({
defaults: {
title: '',
completed: false
},
initialize: function(){
console.log('This model has been initialized.');
this.on('change', function(){
console.log('Values for this model have changed.');
});
this.on('change:title', function(){
console.log('Title value for this model has changed.');
});
}
});
Modelo
Validación
validate: function(attributes){
if(attributes.title === undefined){
return "Remember to set a title for your todo.";
}
},
initialize: function(){
console.log('This model has been initialized.');
this.on("invalid", function(model, error){
console.log(error);
});
}
var myTodo = new Todo();
myTodo.set('completed', true, {validate: true}); // logs: Remember to
set a title for your todo.
console.log(myTodo.get('completed')); // logs: false
console.log(myTodo.validationError) //logs: Remember to set a title
for your todo.
Modelo
Dependencias
●
Vista
Vista
var TodoView = Backbone.View.extend({
tagName: 'ul',
className: 'container ui-corner',
id: 'todos'
template: _.template( $('item-template').html() ),
render: function() {
this.$el.html( this.template( this.model.toJSON() ) );
return this;
}
});
var todoView = new TodoView();
console.log(todosView.el); //logs <ul id="todos"
class="container"></ul>
Eventos
var TodoView = Backbone.View.extend({
tagName: 'li',
events: {
'click .toggle': 'toggleCompleted',
'dblclick label': 'edit',
'keypress .edit': 'updateOnEnter',
'click .destroy': 'clear',
'blur .edit': 'close'
},
edit:function(){
},
Vista
Eventos
var TodoView = Backbone.View.extend({
initialize: function() {
this.model.bind('change', _.bind(this.render, this));
}
});
Vista
Dependencias
●
Colecciones
Colecciones
var Todo = Backbone.Model.extend({
defaults: {
title: '',
completed: false
}
});
var TodosCollection = Backbone.Collection.extend({
model: Todo
});
var myTodo = new Todo({title:'Read the whole book', id: 2});
var todos = new TodosCollection([myTodo]);
console.log("Collection size: " + todos.length); // Collection size: 1
Añadir, obtener y eliminar modelos
var a = new Todo({ title: 'Go to Jamaica.', id:1}),
b = new Todo({ title: 'Go to China.', id:2}),
c = new Todo({ title: 'Go to Disneyland.', id:3});
var todos = new TodosCollection([a,b]);
console.log("Collection size: " + todos.length);
// Logs: Collection size: 2
todos.add(c);
console.log("Collection size: " + todos.length);
// Logs: Collection size: 3
todos.remove([a,b]);
console.log("Collection size: " + todos.length);
// Logs: Collection size: 1
var todo2 = todos.get(2);
// logs: { title: 'Go to China.', id:2}
Colecciones
Actualizando
var TodosCollection = new Backbone.Collection();
TodosCollection.add([
{ id: 1, title: 'go to Jamaica.', completed: false },
{ id: 2, title: 'go to China.', completed: false },
{ id: 3, title: 'go to Disneyland.', completed: true }
]);
TodosCollection.set([
{ id: 1, title: 'go to Jamaica.', completed: true },
{ id: 2, title: 'go to China.', completed: false },
{ id: 4, title: 'go to Disney World.', completed: false }
]);
Console.log(TodosCollection.toJSON());
// Logs: [ { id: 1, title: 'go to Jamaica.', completed: true },
// { id: 2, title: 'go to China.', completed: false },
// { id: 4, title: 'go to Disney World.', completed: false } ]
Colecciones
Eventos
var TodosCollection = new Backbone.Collection();
TodosCollection.on("change:title", function(model) {
console.log("Changed my mind! I should " + model.get('title'));
});
TodosCollection.add([
{ title: 'go to Jamaica.', completed: false, id: 3 },
]);
var myTodo = TodosCollection.get(3);
myTodo.set('title', 'go fishing');
// Logs: Changed my mind! I should go fishing
Colecciones
Reiniciando
TodosCollection.reset();
TodosCollection.reset([
{ title: 'go to Cuba.', completed: false }
]);
Colecciones
Funciones Underscore
● forEach
● sortBy
● map
● max/min
● pulck
● filter
● indexOf
● any/some
● isEmpty
● groupBy
● pick
● omit
● keys/values
● pairs
● Invert
● chain
Funciones Underscore
● forEach
● sortBy
● map
● max/min
● pulck
● filter
● indexOf
● any/some
● isEmpty
● groupBy
● pick
● omit
● keys/values
● pairs
● Invert
● chain
var sortedByAlphabet = todos.sortBy(function
(todo) {
return todo.get("title").toLowerCase();
});
console.log("- Now sorted: ");
sortedByAlphabet.forEach(function(model){
console.log(model.get('title'));
});
// Above logs:
// - Now sorted:
// go to Austria.
// go to Belgium.
// go to China.
Funciones Underscore
● forEach
● sortBy
● map
● max/min
● pulck
● filter
● indexOf
● any/some
● isEmpty
● groupBy
● pick
● omit
● keys/values
● pairs
● Invert
● chain
todos.max(function(model){
return model.id;
}).id;
todos.min(function(model){
return model.id;
}).id;
Funciones Underscore
● forEach
● sortBy
● map
● max/min
● pulck
● filter
● indexOf
● any/some
● isEmpty
● groupBy
● pick
● omit
● keys/values
● pairs
● Invert
● chain
var collection = new Backbone.Collection([
{ name: 'Tim', age: 5 },
{ name: 'Ida', age: 26 },
{ name: 'Rob', age: 55 }
]);
var filteredNames = collection.chain()
.filter(function(item) { return
item.get('age') > 10; })
.map(function(item) { return
item.get('name'); })
.value();
console.log(filteredNames); // logs: ['Ida',
'Rob']
RESTful Persistence
var Todo = Backbone.Model.extend({
defaults: {
title: '',
completed: false
}
});
var TodosCollection = Backbone.Collection.extend({
model: Todo,
url: '/todos'
});
var todos = new TodosCollection();
todos.fetch(); // sends HTTP GET to /todos
var todo2 = todos.get(2);
todo2.set('title', 'go fishing');
todo2.save(); // sends HTTP PUT to /todos/2
todo2.destroy(); // sends HTTP DELETE to /todos/2
todos.create({title: 'Try out code samples'}); // sends HTTP POST
to /todos
BackBone-sync
Backbone.sync = function(method, model, options) {
switch (method) {
case 'POST':
return MyAPI.create(model, success, error);
case 'PUT':
return MyAPI.update(model, success, error);
case 'PATCH':
return MyAPI.patch(model, success, error);
case 'DELETE':
return MyAPI.destroy(model, success, error);
case 'GET':
if (model.cid) {
return MyAPI.find(model, success, error);
} else {
return MyAPI.findAll(model, success, error);
}
}
Rutas
var TodoRouter = Backbone.Router.extend({
routes: {
"todo/:id" : "getTodo", // http://example.com/#todo/5
"search/:query" : "searchTodos",
// http://example.com/#search/job
"search/:query/p:page" : "searchTodos",
// http://example.com/#search/job/p1
"todos/:id/download/*documentPath" : "downloadDocument",
//http://example.com/#todos/5/download/files/Meeting_schedule.doc
},
searchTodos: function(query, page){
},
downloadDocument: function(id, path){
}
});
var myTodoRouter = new TodoRouter();
Ejemplo práctico
todomvc.com
Ejemplo práctico
Modelo
Template
Template
item-template
Todo
stats-template
Colección
TodoList
Vista
AppView
TodoView
Vista
Rutas
TodoRouter
HTML
<section id="todoapp">
<header id="header">
<h1>todos</h1>
<input id="new-todo" placeholder="What needs to be done?"
autofocus>
</header>
<section id="main">
<input id="toggle-all" type="checkbox">
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list"></ul>
</section>
<footer id="footer"></footer>
</section>
<div id="info">
<p>Double-click to edit a todo</p>
<p>Written by <a href="https://github.com/addyosmani">Addy
Osmani</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</div>
Ejemplo práctico
Templates
<!-- index.html -->
<script type="text/template" id="item-template">
<div class="view">
<input class="toggle" type="checkbox" <%= completed ?
'checked' : '' %>>
<label><%= title %></label>
<button class="destroy"></button>
</div>
<input class="edit" value="<%= title %>">
</script>
Ejemplo práctico
Templates
<!-- index.html -->
<script type="text/template" id="stats-template">
<span id="todo-count"><strong><%= remaining %></strong> <%=
remaining === 1 ? 'item' : 'items' %> left</span>
<ul id="filters">
<li>
<a class="selected" href="#/">All</a>
</li>
<li>
<a href="#/active">Active</a>
</li>
<li>
<a href="#/completed">Completed</a>
</li>
</ul>
<% if (completed) { %>
<button id="clear-completed">Clear completed (<%= completed
%>)</button>
<% } %>
</script>
Ejemplo práctico
Todo Model
var app = app || {};
app.Todo = Backbone.Model.extend({
defaults: {
title: '',
completed: false
},
toggle: function() {
this.save({
completed: !this.get('completed')
});
}
});
Ejemplo práctico
Todo Collection
var TodoList = Backbone.Collection.extend({
model: app.Todo,
completed: function() {
return this.filter(function( todo ) {
return todo.get('completed');
});
},
remaining: function() {
return this.without.apply( this, this.completed() );
},
comparator: function( todo ) {
return todo.get('order');
}
});
app.Todos = new TodoList();
Ejemplo práctico
Application View
app.AppView = Backbone.View.extend({
el: '#todoapp',
statsTemplate: _.template( $('#stats-template').html() ),
initialize: function() {
this.allCheckbox = this.$('#toggle-all')[0];
this.$input = this.$('#new-todo');
this.$footer = this.$('#footer');
this.$main = this.$('#main');
this.listenTo(app.Todos, 'add', this.addOne);
this.listenTo(app.Todos, 'reset', this.addAll);
this.listenTo(app.Todos, 'change:completed', this.filterOne);
this.listenTo(app.Todos,'filter', this.filterAll);
this.listenTo(app.Todos, 'all', this.render);
app.Todos.fetch();
}
});
Ejemplo práctico
Application View
app.AppView = Backbone.View.extend({
events: {
'keypress #new-todo': 'createOnEnter',
'click #clear-completed': 'clearCompleted',
'click #toggle-all': 'toggleAllComplete'
},
addOne: function( todo ) {
var view = new app.TodoView({ model: todo });
$('#todo-list').append( view.render().el );
},
addAll: function() {
this.$('#todo-list').html('');
app.Todos.each(this.addOne, this);
}
render: function() {
this.$footer.html(this.statsTemplate({
completed: app.Todos.completed().length,
remaining: app.Todos.remaining().length
}));
},
Ejemplo práctico
Application View
app.AppView = Backbone.View.extend({
newAttributes: function() {
return {
title: this.$input.val().trim(),
order: app.Todos.nextOrder(),
completed: false
};
},
createOnEnter: function( event ) {
if ( event.which !== ENTER_KEY || !this.$input.val().trim() ) {
return;
}
app.Todos.create( this.newAttributes() );
this.$input.val('');
},
});
Ejemplo práctico
Application View
app.AppView = Backbone.View.extend({
clearCompleted: function() {
_.invoke(app.Todos.completed(), 'destroy');
return false;
},
toggleAllComplete: function() {
var completed = this.allCheckbox.checked;
app.Todos.each(function( todo ) {
todo.save({
'completed': completed
});
});
}
});
Ejemplo práctico
Individual Todo View
app.TodoView = Backbone.View.extend({
tagName: 'li',
template: _.template( $('#item-template').html() ),
events: {
'click .toggle': 'togglecompleted',
'dblclick label': 'edit',
'click .destroy': 'clear',
'keypress .edit': 'updateOnEnter',
'blur .edit': 'close'
},
initialize: function() {
this.listenTo(this.model, 'change', this.render);
this.listenTo(this.model, 'destroy', this.remove);
this.listenTo(this.model, 'visible', this.toggleVisible);
},
render: function() {
this.$el.html( this.template( this.model.toJSON() ) );
return this;
},
});
Ejemplo práctico
Individual Todo View
app.TodoView = Backbone.View.extend({
close: function() {
var value = this.$('.edit).val().trim();
if ( value ) {
this.model.save({ title: value });
} else {
this.clear();
}
this.$el.removeClass('editing');
},
updateOnEnter: function( e ) {
if ( e.which === ENTER_KEY ) {
this.close();
}
},
clear: function() {
this.model.destroy();
}
Ejemplo práctico
Todo routing
var Workspace = Backbone.Router.extend({
routes:{
'*filter': 'setFilter'
},
setFilter: function( param ) {
if (param) {
param = param.trim();
}
app.TodoFilter = param || '';
app.Todos.trigger('filter');
}
});
app.TodoRouter = new Workspace();
Backbone.history.start();
Ejemplo práctico
Startup
var app = app || {};
var ENTER_KEY = 13;
$(function() {
new app.AppView().render();
});
Ejemplo práctico
¿Qué nos queda de backbone?
● Frameworks
● MarionetteJS
● Thorax(Handlebars)
● RequireJS – Organización modular
● Backbone.Paginator
● Unit Testing
¿ Preguntas ?

More Related Content

What's hot

05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboards05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboardsDenis Ristic
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5arajivmordani
 
Decoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDDecoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDAleix Vergés
 
06 jQuery #burningkeyboards
06 jQuery  #burningkeyboards06 jQuery  #burningkeyboards
06 jQuery #burningkeyboardsDenis Ristic
 
History of jQuery
History of jQueryHistory of jQuery
History of jQueryjeresig
 
Perkenalan ReasonML
Perkenalan ReasonMLPerkenalan ReasonML
Perkenalan ReasonMLRiza Fahmi
 
Introduction to ReasonML
Introduction to ReasonMLIntroduction to ReasonML
Introduction to ReasonMLRiza Fahmi
 
Testing Web Applications with GEB
Testing Web Applications with GEBTesting Web Applications with GEB
Testing Web Applications with GEBHoward Lewis Ship
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony AppsKris Wallsmith
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationKirill Chebunin
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleHugo Hamon
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2Hugo Hamon
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony AppsKris Wallsmith
 
Web Crawling with NodeJS
Web Crawling with NodeJSWeb Crawling with NodeJS
Web Crawling with NodeJSSylvain Zimmer
 
Nodejs do teste de unidade ao de integração
Nodejs  do teste de unidade ao de integraçãoNodejs  do teste de unidade ao de integração
Nodejs do teste de unidade ao de integraçãoVinícius Pretto da Silva
 
Joe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand DwrJoe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand Dwrdeimos
 
PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2eugenio pombi
 

What's hot (20)

05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboards05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboards
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5a
 
Decoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDDecoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDD
 
06 jQuery #burningkeyboards
06 jQuery  #burningkeyboards06 jQuery  #burningkeyboards
06 jQuery #burningkeyboards
 
ES6 is Nigh
ES6 is NighES6 is Nigh
ES6 is Nigh
 
History of jQuery
History of jQueryHistory of jQuery
History of jQuery
 
Perkenalan ReasonML
Perkenalan ReasonMLPerkenalan ReasonML
Perkenalan ReasonML
 
Introduction to ReasonML
Introduction to ReasonMLIntroduction to ReasonML
Introduction to ReasonML
 
Testing Web Applications with GEB
Testing Web Applications with GEBTesting Web Applications with GEB
Testing Web Applications with GEB
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 Application
 
Drupal, meet Assetic
Drupal, meet AsseticDrupal, meet Assetic
Drupal, meet Assetic
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
Web Crawling with NodeJS
Web Crawling with NodeJSWeb Crawling with NodeJS
Web Crawling with NodeJS
 
Nodejs do teste de unidade ao de integração
Nodejs  do teste de unidade ao de integraçãoNodejs  do teste de unidade ao de integração
Nodejs do teste de unidade ao de integração
 
Joe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand DwrJoe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand Dwr
 
Dollar symbol
Dollar symbolDollar symbol
Dollar symbol
 
PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2
 

Similar to ¿Cómo de sexy puede hacer Backbone mi código?

Frameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHPFrameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHPDan Jesus
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScriptAndrew Dupont
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsJarod Ferguson
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCpootsbook
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejsNick Lee
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptVisual Engineering
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyDavid Padbury
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS ArchitectureEyal Vardi
 
AngularJS Internal
AngularJS InternalAngularJS Internal
AngularJS InternalEyal Vardi
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ EtsyNishan Subedi
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasminePaulo Ragonha
 
ECMAScript2015
ECMAScript2015ECMAScript2015
ECMAScript2015qmmr
 

Similar to ¿Cómo de sexy puede hacer Backbone mi código? (20)

Frameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHPFrameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHP
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejs
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
 
Say It With Javascript
Say It With JavascriptSay It With Javascript
Say It With Javascript
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS Architecture
 
AngularJS Internal
AngularJS InternalAngularJS Internal
AngularJS Internal
 
Backbone js
Backbone jsBackbone js
Backbone js
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
Intro to Sail.js
Intro to Sail.jsIntro to Sail.js
Intro to Sail.js
 
PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
 
Backbone Basics with Examples
Backbone Basics with ExamplesBackbone Basics with Examples
Backbone Basics with Examples
 
Javascript - Beyond-jQuery
Javascript - Beyond-jQueryJavascript - Beyond-jQuery
Javascript - Beyond-jQuery
 
ECMAScript2015
ECMAScript2015ECMAScript2015
ECMAScript2015
 

Recently uploaded

Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 

Recently uploaded (20)

Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 

¿Cómo de sexy puede hacer Backbone mi código?

  • 1. Introducción a Backbone.js Sergio Espín¿Cómo de sexy puede hacer Backbone mi código? Sergio Espín @bytespin
  • 2. ¿Qué es Backbone? ● Librería JavaScript muy ligera para desarrollo de aplicaciones web ● Ofrece: ● Estructura de datos: Modelos y Colecciones ● Interfaz: Vistas y Rutas ● MVC ● RESTful
  • 3. ¿Qué es Backbone? ● Librería JavaScript muy ligera para desarrollo de aplicaciones web ● Ofrece: ● Estructura de datos: Modelos y Colecciones ● Interfaz: Vistas y Rutas ● MV* ● RESTful
  • 6. Modelo var Todo = Backbone.Model.extend({}); var todo1 = new Todo(); console.log(JSON.stringify(todo1)); // Logs: {} var todo2 = new Todo({ title: 'Check the attributes of both model instances in the console.', completed: true }); console.log(JSON.stringify(todo2)); // Logs: {"title":"Check the attributes of both model instances in the console.","completed":true}
  • 7. Inicialización var Todo = Backbone.Model.extend({ initialize: function(){ console.log('This model has been initialized.'); } }); var myTodo = new Todo(); // Logs: This model has been initialized. Modelo
  • 8. Valores por defecto var Todo = Backbone.Model.extend({ defaults: { title: '', completed: false } }); var todo2 = new Todo({ title: 'Check attributes of the logged models in the console.' }); console.log(JSON.stringify(todo2)); // Logs: {"title":"Check attributes of the logged models in the console.","completed":false} Modelo
  • 9. Get, set y toJSON ● Get console.log(todo1.get('completed')); // false ● Set myTodo.set("title", "Title attribute set through Model.set()."); myTodo.set({ title: "Both attributes set through Model.set().", completed: true }); ● ToJSON var todo1Attributes = todo1.toJSON(); console.log(todo1Attributes); // Logs: {"title":"","completed":false} Modelo
  • 10. Cambios en el modelo var Todo = Backbone.Model.extend({ defaults: { title: '', completed: false }, initialize: function(){ console.log('This model has been initialized.'); this.on('change', function(){ console.log('Values for this model have changed.'); }); this.on('change:title', function(){ console.log('Title value for this model has changed.'); }); } }); Modelo
  • 11. Validación validate: function(attributes){ if(attributes.title === undefined){ return "Remember to set a title for your todo."; } }, initialize: function(){ console.log('This model has been initialized.'); this.on("invalid", function(model, error){ console.log(error); }); } var myTodo = new Todo(); myTodo.set('completed', true, {validate: true}); // logs: Remember to set a title for your todo. console.log(myTodo.get('completed')); // logs: false console.log(myTodo.validationError) //logs: Remember to set a title for your todo. Modelo
  • 13. Vista var TodoView = Backbone.View.extend({ tagName: 'ul', className: 'container ui-corner', id: 'todos' template: _.template( $('item-template').html() ), render: function() { this.$el.html( this.template( this.model.toJSON() ) ); return this; } }); var todoView = new TodoView(); console.log(todosView.el); //logs <ul id="todos" class="container"></ul>
  • 14. Eventos var TodoView = Backbone.View.extend({ tagName: 'li', events: { 'click .toggle': 'toggleCompleted', 'dblclick label': 'edit', 'keypress .edit': 'updateOnEnter', 'click .destroy': 'clear', 'blur .edit': 'close' }, edit:function(){ }, Vista
  • 15. Eventos var TodoView = Backbone.View.extend({ initialize: function() { this.model.bind('change', _.bind(this.render, this)); } }); Vista
  • 17. Colecciones var Todo = Backbone.Model.extend({ defaults: { title: '', completed: false } }); var TodosCollection = Backbone.Collection.extend({ model: Todo }); var myTodo = new Todo({title:'Read the whole book', id: 2}); var todos = new TodosCollection([myTodo]); console.log("Collection size: " + todos.length); // Collection size: 1
  • 18. Añadir, obtener y eliminar modelos var a = new Todo({ title: 'Go to Jamaica.', id:1}), b = new Todo({ title: 'Go to China.', id:2}), c = new Todo({ title: 'Go to Disneyland.', id:3}); var todos = new TodosCollection([a,b]); console.log("Collection size: " + todos.length); // Logs: Collection size: 2 todos.add(c); console.log("Collection size: " + todos.length); // Logs: Collection size: 3 todos.remove([a,b]); console.log("Collection size: " + todos.length); // Logs: Collection size: 1 var todo2 = todos.get(2); // logs: { title: 'Go to China.', id:2} Colecciones
  • 19. Actualizando var TodosCollection = new Backbone.Collection(); TodosCollection.add([ { id: 1, title: 'go to Jamaica.', completed: false }, { id: 2, title: 'go to China.', completed: false }, { id: 3, title: 'go to Disneyland.', completed: true } ]); TodosCollection.set([ { id: 1, title: 'go to Jamaica.', completed: true }, { id: 2, title: 'go to China.', completed: false }, { id: 4, title: 'go to Disney World.', completed: false } ]); Console.log(TodosCollection.toJSON()); // Logs: [ { id: 1, title: 'go to Jamaica.', completed: true }, // { id: 2, title: 'go to China.', completed: false }, // { id: 4, title: 'go to Disney World.', completed: false } ] Colecciones
  • 20. Eventos var TodosCollection = new Backbone.Collection(); TodosCollection.on("change:title", function(model) { console.log("Changed my mind! I should " + model.get('title')); }); TodosCollection.add([ { title: 'go to Jamaica.', completed: false, id: 3 }, ]); var myTodo = TodosCollection.get(3); myTodo.set('title', 'go fishing'); // Logs: Changed my mind! I should go fishing Colecciones
  • 21. Reiniciando TodosCollection.reset(); TodosCollection.reset([ { title: 'go to Cuba.', completed: false } ]); Colecciones
  • 22. Funciones Underscore ● forEach ● sortBy ● map ● max/min ● pulck ● filter ● indexOf ● any/some ● isEmpty ● groupBy ● pick ● omit ● keys/values ● pairs ● Invert ● chain
  • 23. Funciones Underscore ● forEach ● sortBy ● map ● max/min ● pulck ● filter ● indexOf ● any/some ● isEmpty ● groupBy ● pick ● omit ● keys/values ● pairs ● Invert ● chain var sortedByAlphabet = todos.sortBy(function (todo) { return todo.get("title").toLowerCase(); }); console.log("- Now sorted: "); sortedByAlphabet.forEach(function(model){ console.log(model.get('title')); }); // Above logs: // - Now sorted: // go to Austria. // go to Belgium. // go to China.
  • 24. Funciones Underscore ● forEach ● sortBy ● map ● max/min ● pulck ● filter ● indexOf ● any/some ● isEmpty ● groupBy ● pick ● omit ● keys/values ● pairs ● Invert ● chain todos.max(function(model){ return model.id; }).id; todos.min(function(model){ return model.id; }).id;
  • 25. Funciones Underscore ● forEach ● sortBy ● map ● max/min ● pulck ● filter ● indexOf ● any/some ● isEmpty ● groupBy ● pick ● omit ● keys/values ● pairs ● Invert ● chain var collection = new Backbone.Collection([ { name: 'Tim', age: 5 }, { name: 'Ida', age: 26 }, { name: 'Rob', age: 55 } ]); var filteredNames = collection.chain() .filter(function(item) { return item.get('age') > 10; }) .map(function(item) { return item.get('name'); }) .value(); console.log(filteredNames); // logs: ['Ida', 'Rob']
  • 26. RESTful Persistence var Todo = Backbone.Model.extend({ defaults: { title: '', completed: false } }); var TodosCollection = Backbone.Collection.extend({ model: Todo, url: '/todos' }); var todos = new TodosCollection(); todos.fetch(); // sends HTTP GET to /todos var todo2 = todos.get(2); todo2.set('title', 'go fishing'); todo2.save(); // sends HTTP PUT to /todos/2 todo2.destroy(); // sends HTTP DELETE to /todos/2 todos.create({title: 'Try out code samples'}); // sends HTTP POST to /todos
  • 27. BackBone-sync Backbone.sync = function(method, model, options) { switch (method) { case 'POST': return MyAPI.create(model, success, error); case 'PUT': return MyAPI.update(model, success, error); case 'PATCH': return MyAPI.patch(model, success, error); case 'DELETE': return MyAPI.destroy(model, success, error); case 'GET': if (model.cid) { return MyAPI.find(model, success, error); } else { return MyAPI.findAll(model, success, error); } }
  • 28. Rutas var TodoRouter = Backbone.Router.extend({ routes: { "todo/:id" : "getTodo", // http://example.com/#todo/5 "search/:query" : "searchTodos", // http://example.com/#search/job "search/:query/p:page" : "searchTodos", // http://example.com/#search/job/p1 "todos/:id/download/*documentPath" : "downloadDocument", //http://example.com/#todos/5/download/files/Meeting_schedule.doc }, searchTodos: function(query, page){ }, downloadDocument: function(id, path){ } }); var myTodoRouter = new TodoRouter();
  • 31. HTML <section id="todoapp"> <header id="header"> <h1>todos</h1> <input id="new-todo" placeholder="What needs to be done?" autofocus> </header> <section id="main"> <input id="toggle-all" type="checkbox"> <label for="toggle-all">Mark all as complete</label> <ul id="todo-list"></ul> </section> <footer id="footer"></footer> </section> <div id="info"> <p>Double-click to edit a todo</p> <p>Written by <a href="https://github.com/addyosmani">Addy Osmani</a></p> <p>Part of <a href="http://todomvc.com">TodoMVC</a></p> </div> Ejemplo práctico
  • 32. Templates <!-- index.html --> <script type="text/template" id="item-template"> <div class="view"> <input class="toggle" type="checkbox" <%= completed ? 'checked' : '' %>> <label><%= title %></label> <button class="destroy"></button> </div> <input class="edit" value="<%= title %>"> </script> Ejemplo práctico
  • 33. Templates <!-- index.html --> <script type="text/template" id="stats-template"> <span id="todo-count"><strong><%= remaining %></strong> <%= remaining === 1 ? 'item' : 'items' %> left</span> <ul id="filters"> <li> <a class="selected" href="#/">All</a> </li> <li> <a href="#/active">Active</a> </li> <li> <a href="#/completed">Completed</a> </li> </ul> <% if (completed) { %> <button id="clear-completed">Clear completed (<%= completed %>)</button> <% } %> </script> Ejemplo práctico
  • 34. Todo Model var app = app || {}; app.Todo = Backbone.Model.extend({ defaults: { title: '', completed: false }, toggle: function() { this.save({ completed: !this.get('completed') }); } }); Ejemplo práctico
  • 35. Todo Collection var TodoList = Backbone.Collection.extend({ model: app.Todo, completed: function() { return this.filter(function( todo ) { return todo.get('completed'); }); }, remaining: function() { return this.without.apply( this, this.completed() ); }, comparator: function( todo ) { return todo.get('order'); } }); app.Todos = new TodoList(); Ejemplo práctico
  • 36. Application View app.AppView = Backbone.View.extend({ el: '#todoapp', statsTemplate: _.template( $('#stats-template').html() ), initialize: function() { this.allCheckbox = this.$('#toggle-all')[0]; this.$input = this.$('#new-todo'); this.$footer = this.$('#footer'); this.$main = this.$('#main'); this.listenTo(app.Todos, 'add', this.addOne); this.listenTo(app.Todos, 'reset', this.addAll); this.listenTo(app.Todos, 'change:completed', this.filterOne); this.listenTo(app.Todos,'filter', this.filterAll); this.listenTo(app.Todos, 'all', this.render); app.Todos.fetch(); } }); Ejemplo práctico
  • 37. Application View app.AppView = Backbone.View.extend({ events: { 'keypress #new-todo': 'createOnEnter', 'click #clear-completed': 'clearCompleted', 'click #toggle-all': 'toggleAllComplete' }, addOne: function( todo ) { var view = new app.TodoView({ model: todo }); $('#todo-list').append( view.render().el ); }, addAll: function() { this.$('#todo-list').html(''); app.Todos.each(this.addOne, this); } render: function() { this.$footer.html(this.statsTemplate({ completed: app.Todos.completed().length, remaining: app.Todos.remaining().length })); }, Ejemplo práctico
  • 38. Application View app.AppView = Backbone.View.extend({ newAttributes: function() { return { title: this.$input.val().trim(), order: app.Todos.nextOrder(), completed: false }; }, createOnEnter: function( event ) { if ( event.which !== ENTER_KEY || !this.$input.val().trim() ) { return; } app.Todos.create( this.newAttributes() ); this.$input.val(''); }, }); Ejemplo práctico
  • 39. Application View app.AppView = Backbone.View.extend({ clearCompleted: function() { _.invoke(app.Todos.completed(), 'destroy'); return false; }, toggleAllComplete: function() { var completed = this.allCheckbox.checked; app.Todos.each(function( todo ) { todo.save({ 'completed': completed }); }); } }); Ejemplo práctico
  • 40. Individual Todo View app.TodoView = Backbone.View.extend({ tagName: 'li', template: _.template( $('#item-template').html() ), events: { 'click .toggle': 'togglecompleted', 'dblclick label': 'edit', 'click .destroy': 'clear', 'keypress .edit': 'updateOnEnter', 'blur .edit': 'close' }, initialize: function() { this.listenTo(this.model, 'change', this.render); this.listenTo(this.model, 'destroy', this.remove); this.listenTo(this.model, 'visible', this.toggleVisible); }, render: function() { this.$el.html( this.template( this.model.toJSON() ) ); return this; }, }); Ejemplo práctico
  • 41. Individual Todo View app.TodoView = Backbone.View.extend({ close: function() { var value = this.$('.edit).val().trim(); if ( value ) { this.model.save({ title: value }); } else { this.clear(); } this.$el.removeClass('editing'); }, updateOnEnter: function( e ) { if ( e.which === ENTER_KEY ) { this.close(); } }, clear: function() { this.model.destroy(); } Ejemplo práctico
  • 42. Todo routing var Workspace = Backbone.Router.extend({ routes:{ '*filter': 'setFilter' }, setFilter: function( param ) { if (param) { param = param.trim(); } app.TodoFilter = param || ''; app.Todos.trigger('filter'); } }); app.TodoRouter = new Workspace(); Backbone.history.start(); Ejemplo práctico
  • 43. Startup var app = app || {}; var ENTER_KEY = 13; $(function() { new app.AppView().render(); }); Ejemplo práctico
  • 44. ¿Qué nos queda de backbone? ● Frameworks ● MarionetteJS ● Thorax(Handlebars) ● RequireJS – Organización modular ● Backbone.Paginator ● Unit Testing