Tenemos el siguiente modelo, donde parseamos los valores al modelo a través de JSON. Donde el identificador es ident.
define(["Backbone"], function(Backbone){ var BookModel = Backbone.Model.extend({ parse: function(item) { return { ident: item.ident, nombre: item.nombre, autor: item.autor }; } }); return BookModel; });En nuestra aplicación mostramos una lista de libros, y cada uno de ellos tiene asociado un botón 'Detalle' que te permite ir a una página de detalle del libro. La función que permite pintar la vista del detalle del libro es la siguiente:
render: function() { console.log('DetailBookView - render'); var self = this; //Obtenemos el identificador del libro a mostrar a traves de parametros de la vista var idBook = self.options.idBook; //creamos un objeto del tipo Libro Collection var ltBooks = new BookCollection(); //Reseteamos la coleccion con los valores que antes hemos almacenado en memoria para evitar hacer otra llamada REST ltBooks.reset(JSON.parse(sessionStorage.getItem("findBooks"))); //hacemos una busqueda del objeto del cual vamos a mostrar el detalle this.book = _.find(ltBooks.models,function(i) {return i.attributes.ident==idBook;}); console.log('BOOK ID INTERNAL: '+this.book.id); //pintamos el detalle en la pagina html (indicada anteriormente) $(self.el).html(self.template({ book: this.book })); return self; }Tras pintar el detalle, y modificar el formulario accedemos a la función guardar:
saveBook : function(){ console.log('BOOK ID INTERNAL: '+this.book.id); //Almacenamos los valores de los atributos que han tenido cambios var atributos = { nombre : $("#nombre").val(), autor : $("#autor").val() }; //realizamos el save, y backbone se encargara de hacer la llamada REST var retorno = this.book.save(atributos, {success :function(model, response){ console.log("success save "); }, error: function(model, response){ console.log("error save"); console.log("model "+JSON.stringify(model)); console.log("response "+JSON.stringify(response)); }}); history.back(); }Al realizar la llamada al metodo 'save'. Backbone se debe de encargar de realizar una llamada tipo PUT, que es la indicada para realizar modificaciones de elementos. El problema en nuestro caso es que en vez de realizar la llamada PUT, realiza una POST (Esto lo podemos comprobar facilmente con el firebug). Es decir que Backbone no entiende que sea una modificación de un elemento existente si no que se trata de la creación de un nuevo elemento. Se nos puede dar una pista del mal funcionamiento debido a que cada vez que imprimimos por pantalla el ID interno que maneja Backbone, este es undefined.
Mirando la documentación de Backbone, este mismo indica aquí, que siempre considerará a un modelo como nuevo si no tiene ningún id asociado. Y aunque en principio hay una diferencia entre el atributo id y el identificador propio del modelo, parece que la raiz del problema se encuentra ahí.
¿Cual es la solución?, pues en nuestro caso es bastante sencilla, solo tenemos que indicar que el atributo identificador se pase a llamar 'id' y no 'ident' como esta actualmente en el modelo (Tener en cuenta dicho detalle para modificar el atributo tanto en los ficheros javascript como por parte del servicio REST).
define(["Backbone"], function(Backbone){ var BookModel = Backbone.Model.extend({ parse: function(item) { return { id: item.ident, nombre: item.nombre, autor: item.autor }; } }); return BookModel; });Una vez realizado este cambio, cuando hagamos la operación de modificar, Backbone realizará una llamada PUT y en las trazas podremos observar como el atributo interno ID ya no es undefined.
No hay comentarios:
Publicar un comentario