¿Formas de guardar datos del modelo Backbone.js?


86

Estoy más interesado en el desarrollo de front-end y recientemente comencé a explorar Backbone.js en mi aplicación. Quiero conservar los datos del modelo en el servidor.

¿Podría explicarme las diversas formas de guardar los datos del modelo (usando el formato json)? Estoy usando Java en el lado del servidor. También he visto principalmente que se usa REST para guardar datos. Como estoy más en el desarrollo de front-end, no estoy al tanto de REST y otras cosas similares.

Sería genial si alguien pudiera explicarme el proceso con un ejemplo simple.

Respuestas:


272

Básicamente, los modelos tienen una propiedad llamada atributos, que son los diversos valores que puede tener un determinado modelo. Backbone usa objetos JSON como una forma simple de completar estos valores usando varios métodos que toman objetos JSON. Ejemplo:

Donuts = Backbone.Model.extend({
    defaults: {
        flavor: 'Boston Cream',  // Some string
        price: '0.50'  // Dollars
    }
});

Para completar el modelo, hay varias formas de hacerlo. Por ejemplo, puede configurar su instancia de modelo pasando un JSON O use un método llamado set () que toma un objeto JSON de atributos.

myDonut = new Donut({'flavor':'lemon', 'price':'0.75'});
mySecondHelping = new Donut();
mySecondHelping.set({'flavor':'plain', 'price':'0.25'});

console.log(myDonut.toJSON());
// {'flavor':'lemon', 'price':'0.75'}
console.log(mySecondHelping.toJSON());
// {'flavor':'plain', 'price':'0.25'}

Entonces, esto nos lleva a guardar modelos y conservarlos en un servidor. Hay una gran cantidad de detalles sobre "¿Qué es REST / RESTful?" Y es un poco difícil explicar todo esto en una breve propaganda aquí. Específicamente con respecto al ahorro de REST y Backbone, lo que debe entender es la semántica de las solicitudes HTTP y lo que está haciendo con sus datos.

Probablemente esté acostumbrado a dos tipos de solicitudes HTTP. OBTENER y PUBLICAR. En un entorno RESTful, estos verbos tienen un significado especial para usos específicos que asume Backbone. Cuando desea obtener un determinado recurso del servidor (por ejemplo, el modelo de rosquilla que guardé la última vez, una entrada de blog, una especificación de computadora) y ese recurso existe, realiza una solicitud GET. Por el contrario, cuando desee crear un nuevo recurso, utilice POST.

Antes de ingresar a Backbone, nunca había tocado los siguientes dos métodos de solicitud HTTP. PONER y BORRAR. Estos dos verbos también tienen un significado específico para Backbone. Cuando desee actualizar un recurso (por ejemplo, cambiar el sabor de una dona de limón a una dona de limón, etc.), utilice una solicitud PUT. Cuando desee eliminar ese modelo del servidor por completo, utilice una solicitud DELETE.

Estos conceptos básicos son muy importantes porque con su aplicación RESTful, probablemente tendrá una designación de URI que realizará la tarea adecuada según el tipo de verbo de solicitud que use. Por ejemplo:

// The URI pattern
http://localhost:8888/donut/:id

// My URI call
http://localhost:8888/donut/17

Si hago un GET a ese URI, obtendría un modelo de rosquilla con un ID de 17. El: id depende de cómo lo guarde en el servidor. Este podría ser solo el ID de su recurso de dona en su tabla de base de datos.

Si hago un PUT a ese URI con nuevos datos, lo actualizaría y lo guardaría. Y si ELIMO a ese URI, lo eliminaría de mi sistema.

Con POST, dado que aún no ha creado un recurso, no tendrá un ID de recurso establecido. Tal vez el objetivo de URI que quiero crear recursos es simplemente este:

http://localhost:8888/donut

Ningún fragmento de ID en el URI. Todos estos diseños de URI dependen de usted y de cómo piensa en sus recursos. Pero con respecto al diseño RESTful, tengo entendido que desea mantener los verbos de sus acciones en su solicitud HTTP y los recursos como sustantivos que hacen que los URI sean fáciles de leer y amigables para los humanos.

¿Sigues conmigo? :-)

Así que volvamos a pensar en Backbone. Backbone es maravilloso porque hace mucho trabajo por ti. Para guardar nuestra dona y secondHelping, simplemente hacemos esto:

myDonut.save();
mySecondHelping.save();

Backbone es inteligente. Si acaba de crear un recurso de dona, no tendrá una identificación del servidor. Tiene algo llamado cID, que es lo que Backbone usa internamente, pero como no tiene una identificación oficial, sabe que debe crear un nuevo recurso y envía una solicitud POST. Si obtuvo su modelo del servidor, probablemente tendrá una identificación si todo estaba bien. En este caso, cuando guarde () Backbone asume que desea actualizar el servidor y enviará un PUT. Para obtener un recurso específico, usaría el método Backbone .fetch () y envía una solicitud GET. Cuando llamas .destroy () en un modelo, enviará DELETE.

En los ejemplos anteriores, nunca le dije explícitamente a Backbone dónde está el URI. Hagámoslo en el siguiente ejemplo.

thirdHelping = Backbone.Model.extend({
    url: 'donut'
});
thirdHelping.set({id:15});  // Set the id attribute of model to 15
thirdHelping.fetch();  // Backbone assumes this model exists on server as ID 15

Backbone OBTENDRÁ la tercera ayuda http://localhost:8888/donut/15. Simplemente agregará / donut stem a la raíz de su sitio.

Si TODAVÍA estás conmigo, bien. Yo creo que. A menos que esté confundido. Pero seguiremos adelante de todos modos. La segunda parte de esto es el lado del SERVIDOR. Hemos hablado de diferentes verbos de HTTP y los significados semánticos detrás de esos verbos. Significados que usted, Backbone y su servidor deben compartir.

Su servidor debe comprender la diferencia entre una solicitud GET, POST, PUT y DELETE. Como vio en los ejemplos anteriores, GET, PUT y DELETE podrían apuntar al mismo URI. http://localhost:8888/donut/07A menos que su servidor pueda diferenciar entre estas solicitudes HTTP, estará muy confundido en cuanto a qué hacer con ese recurso.

Aquí es cuando empiezas a pensar en el código final de tu servidor RESTful. A algunas personas les gusta Ruby, a otras les gusta .net, a mí me gusta PHP. Particularmente me gusta el micro-framework SLIM PHP. SLIM PHP es un micro-framework que tiene un conjunto de herramientas muy elegante y simple para manejar actividades RESTful. Puede definir rutas (URI) como en los ejemplos anteriores y dependiendo de si la llamada es GET, POST, PUT o DELETE, ejecutará el código correcto. Existen otras soluciones similares a SLIM como Recess, Tonic. Creo que los frameworks más grandes como Cake y CodeIgniter también hacen cosas similares, aunque a mí me gusta lo mínimo. ¿Dije que me gusta Slim? ;-)

Esto es lo que podría lucir el código del extracto en el servidor (es decir, específicamente con respecto a las rutas).

$app->get('/donut/:id', function($id) use ($app) {
    // get donut model with id of $id from database.
    $donut = ...

    // Looks something like this maybe:
    // $donut = array('id'=>7, 'flavor'=>'chocolate', 'price'=>'1.00')

    $response = $app->response();
    $response['Content-Type'] = 'application/json';
    $response->body(json_encode($donut));
});

Aquí es importante tener en cuenta que Backbone espera un objeto JSON. Siempre haga que su servidor designe el tipo de contenido como 'aplicación / json' y codifíquelo en formato json si puede. Luego, cuando Backbone recibe el objeto JSON, sabe cómo completar el modelo que lo solicitó.

Con SLIM PHP, las rutas funcionan de manera bastante similar a las anteriores.

$app->post('/donut', function() use ($app) {
    // Code to create new donut
    // Returns a full donut resource with ID
});
$app->put('/donut/:id', function($id) use ($app) {
    // Code to update donut with id, $id
    $response = $app->response();
    $response->status(200);  // OK!
    // But you can send back other status like 400 which can trigger an error callback.
});
$app->delete('/donut/:id', function($id) use ($app) {
    // Code to delete donut with id, $id
    // Bye bye resource
});

¡Así que casi has hecho el viaje de ida y vuelta completo! Ve por un refresco. Me gusta Diet Mountain Dew. Consígueme uno también.

Una vez que su servidor procesa una solicitud, hace algo con la base de datos y el recurso, prepara una respuesta (ya sea un número de estado http simple o un recurso JSON completo), los datos vuelven a Backbone para su procesamiento final.

Con sus métodos save (), fetch (), etc., puede agregar devoluciones de llamada opcionales en caso de éxito y error. Aquí hay un ejemplo de cómo configuré este pastel en particular:

Cake = Backbone.Model.extend({
    defaults: {
        type: 'plain',
        nuts: false
    },
    url: 'cake'
});

myCake = new Cake();
myCake.toJSON()  // Shows us that it is a plain cake without nuts

myCake.save({type:'coconut', nuts:true}, {
    wait:true,
    success:function(model, response) {
        console.log('Successfully saved!');
    },
    error: function(model, error) {
        console.log(model.toJSON());
        console.log('error.responseText');
    }
});

// ASSUME my server is set up to respond with a status(403)
// ASSUME my server responds with string payload saying 'we don't like nuts'

Hay un par de cosas diferentes sobre este ejemplo que. Verá que para mi pastel, en lugar de establecer () los atributos antes de guardar, simplemente pasé los nuevos atributos a mi llamada de guardado. Backbone es bastante ninja en tomar datos JSON por todas partes y manejarlos como un campeón. Entonces quiero guardar mi pastel con cocos y nueces. (¿Son 2 nueces?) De todos modos, pasé dos objetos a mi salvación. Los atributos del objeto JSON Y algunas opciones. El primero, {esperar: verdadero} significa que no actualice mi modelo del lado del cliente hasta que el viaje del lado del servidor sea exitoso. La devolución de llamada exitosa se producirá cuando el servidor devuelva una respuesta con éxito. Sin embargo, dado que este ejemplo da como resultado un error (un estado distinto de 200 indicará a Backbone que use la devolución de llamada de error) obtenemos una representación del modelo sin los cambios. Aún debe ser simple y sin nueces. También tenemos acceso al objeto de error que envió el servidor. Enviamos una cadena, pero podría ser un objeto de error JSON con más propiedades. Se encuentra en el atributo error.responseText. Sí, 'no nos gustan las nueces'.

Felicidades. Ha realizado su primer viaje de ida y vuelta bastante completo desde la configuración de un modelo, guardándolo en el servidor y viceversa. Espero que esta respuesta épica te dé una IDEA de cómo todo esto se une. Por supuesto, hay muchos detalles que estoy cruzando, pero las ideas básicas de Backbone save, verbos RESTful, acciones del lado del servidor, Response están aquí. Siga revisando la documentación de Backbone (que es muy fácil de leer en comparación con otros documentos) pero tenga en cuenta que esto lleva tiempo para entenderlo. Cuanto más lo hagas, más fluido serás. Aprendo algo nuevo con Backbone todos los días y se vuelve muy divertido a medida que comienzas a dar saltos y ves que tu fluidez en este marco crece. :-)

¡Feliz codificación!

EDITAR: Recursos que pueden ser útiles:

Otras respuestas similares en SO: Cómo generar ID de modelo con Backbone

En REST: http://rest.elkstein.org/ http://www.infoq.com/articles/rest-introduction http://www.recessframework.org/page/towards-restful-php-5-basic- consejos


9
Terminé volviéndome un poco loco con esto. Recuerdo cuando empecé Backbone y tenía preguntas como las del autor de la pregunta y me divertí demasiado escribiendo una respuesta. Estoy seguro de que en mi prisa he cometido algunos errores o me he perdido algún importante "¡ah-ha!" facetas, así que si lo hice, házmelo saber. :-P
jmk2142

6
Respuesta alucinante por decir lo menos ... estoy tratando de comprender todas las cosas que mencionaste ... lo de REST parece un poco difícil, aunque tienes razón, seguramente no puedes explicarme DESCANSO dentro de esta pregunta ... Yo ' Revisaré las cosas nuevamente y lo aceptaré en algún tiempo ... Gracias nuevamente por la respuesta detallada ...
testndtv

2
Cuando tenga tiempo, actualizaré mi respuesta con una lista de buenas referencias que pueden ayudarlo en la búsqueda. No puedo darte una espada de madera para enfrentarte al mundo peligroso, pero puedo darte los enlaces de recursos de los sitios que me han ayudado. :-)
jmk2142

5
@testndtv ¿Terminé respondiendo tu pregunta? Se agradecería una marca √.
jmk2142

2
No hay duda de que respondió la pregunta de una manera más de la esperada ... He aceptado la respuesta ahora ... Muchas gracias de nuevo por la ayuda ..
testndtv
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.