Skip to content

Instantly share code, notes, and snippets.

@picodotdev
Last active December 16, 2015 17:19
Ejemplo lista de tareas con Backbone, RESTEasy y Tapestry http://elblogdepicodev.blogspot.com/2013/04/ejemplo-lista-de-tareas-con-backbone.html
$ git clone git://github.com/picodotdev/elblogdepicodev.git
$ cd elblogdepicodev/BackboneREST
$ ./gradlew tomcatRun
# Abrir en el navegador http://localhost:8080/BackboneREST/Index
<script id="tareas-template" type="text/template">
<![CDATA[
<input type="text" name="nuevaTarea" value="" placeholder="Introduce una nueva tarea"/>
<ul id="lista-tareas" class="unstyled"></ul>
<div id="estado"></div>
<input type="button" name="limpiar" value="Limpiar" class="btn"/>
]]>
</script>
<script id="tarea-template" type="text/template">
<![CDATA[
<label class="checkbox">
<input id="{{id}}" type="checkbox" name="completada" {{attrs.checked}}/> <span class="{{attrs.completada}}">{{descripcion}}</span>
</label>
]]>
</script>
<script id="estado-template" type="text/template">
<![CDATA[
{{#total}}
{{completadas}} tareas de {{total}} completadas
{{/total}}
{{^total}}
¡Muy bien! has completado todas las tareas
{{/total}}
]]>
</script>
define(['tareas'], function(tareas) {
var tareasApp = new tareas.TareasApp({el: '#tareas'});
// Cargar los datos iniciales de la lista de tareas
// Usar los datos precargados en la página, para evitar una petición
// al servidor, los datos se incluyen en la página html de la aplicación.
//tareasApp.resetTareas(tareas);
// Aunque en la documentación de backbone recomiendan precargar los datos en la
// página, esto impide cachearla, dependiendo
// de la página tal vez sea mejor cachear la página y pedir los datos
// en una petición AJAX.
tareasApp.fetch();
});
var Tarea = Backbone.Model.extend({
urlRoot : 'rest/tareas/tarea',
defaults: {
id: null,
descripcion: '',
completada: false
},
toPlantilla: function() {
var json = this.toJSON();
json.attrs = {
checked: (this.get('completada')?'checked':null),
completada: (this.get('completada')?'completada':null)
};
return json;
}
});
var Tareas = Backbone.Collection.extend({
url: 'rest/tareas',
model: Tarea,
findCompletadas: function() {
return this.models.filter(function(o) {
return o.get('completada');
});
},
removeCompletadas: function() {
_.each(this.findCompletadas(), function(o) {
o.destroy();
});
}
});
var TareaView = Backbone.View.extend({
tagName: 'li',
className: 'tarea',
events: {
"change input[name='completada']": 'onChangeCompletada'
},
initialize: function() {
_.bindAll(this);
this.model.on('change', this.render);
this.model.on('remove', this.remove);
this.render();
},
render: function() {
var texto = render('#tarea-template', this.model.toPlantilla());
$(this.el).html(texto);
},
// Eventos
onChangeCompletada: function() {
var completada = $("input[name='completada']", this.el).is(':checked');
this.model.set('completada', completada);
this.model.save();
}
});
var TareasApp = Backbone.View.extend({
events: {
"keypress input[name='nuevaTarea']": 'onKeypressNuevaTarea',
"click input[name='limpiar']": 'onClickLimpiar'
},
initialize: function() {
_.bindAll(this);
this.tareas = new Tareas();
this.tareas.on('add', this.render);
this.tareas.on('remove', this.render);
this.tareas.on('change', this.render);
this.tareas.on('reset', this.reset);
var texto = render('#tareas-template', null);
$(this.el).html(texto);
this.render();
},
render: function() {
var completadas = this.tareas.findCompletadas().length;
var total = this.tareas.length;
// Habilitar/deshabilitar el botón de limpiar tareas completadas
if (completadas == 0) {
$("input[name='limpiar']", this.el).attr('disabled', 'disabled');
} else {
$("input[name='limpiar']", this.el).removeAttr('disabled');
}
// Cambiar el mensaje de estado de las tareas
var texto = render('#estado-template', {completadas: completadas, total: total});
$('#estado', this.el).html(texto);
},
reset: function() {
this.tareas.each(function(o) {
var vista = new TareaView({model: o});
$('#lista-tareas', this.el).append(vista.el);
}, this);
this.render();
},
// Métodos
addTarea: function(tarea) {
tarea.save();
this.tareas.add(tarea);
var vista = new TareaView({model: tarea});
$('#lista-tareas', this.el).append(vista.el);
},
resetTareas: function(tareas) {
this.tareas.reset(tareas);
},
fetch: function() {
this.tareas.fetch();
},
// Eventos
onKeypressNuevaTarea: function(event) {
// Comprobar si la tecla pulsada es el return
if (event.which == 13) {
var input = $("input[name='nuevaTarea']", this.el);
var descripcion = input.val();
descripcion = trim(descripcion);
// Comprobar si se ha introducido descripción de la tarea
if (descripcion == '') {
return;
}
// Añadir la tarea y limpiar el input
var tarea = new Tarea({ descripcion: descripcion, completada: false });
this.addTarea(tarea);
input.val('');
}
},
onClickLimpiar: function() {
this.tareas.removeCompletadas();
}
});
package es.com.blogspot.elblogdepicodev.todo.rest;
import java.util.Collection;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/tareas")
public interface TareasResource {
@Path("/tarea")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Tarea createTarea(Tarea tarea);
@Path("/")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Collection<Tarea> readTareas();
@Path("/tarea/{id}")
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Tarea updateTarea(Tarea tarea);
@Path("/tarea/{id}")
@DELETE
public void deleteTarea(@PathParam("id") Long id);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment