backbone.js usa diferentes URL para guardar y buscar modelos
(4)
Mi back-end tiene dos páginas separadas, una para manejar la solicitud de guardar el modelo y la otra para la obtención del modelo.
¿Cuál es el mejor enfoque para llamar a save () y fetch () para usar diferentes URL? Gracias.
Editar: Después de estudiar la fuente anotada, veo que uno realmente puede proporcionar un hash de options
para fetch y save
//taken from backbone source:
save : function(attrs, options) {
options || (options = {});
if (attrs && !this.set(attrs, options)) return false;
var model = this;
var success = options.success;
options.success = function(resp, status, xhr) {
if (!model.set(model.parse(resp, xhr), options)) return false;
if (success) success(model, resp, xhr);
};
options.error = wrapError(options.error, model, options);
var method = this.isNew() ? ''create'' : ''update'';
return (this.sync || Backbone.sync).call(this, method, this, options);
},
En el guardado, ¿qué propósito attrs
los attrs
? Acabo de llamar myModel.save () sin pasar nada y siempre ha sido hashing los atributos de mi modelo correctamente. Pero ahora que quiero proporcionar un ''url de guardado'' y estoy tentado de llamar
myModel.save(undefined, {
url: ''myPath''
})
con el indefinido requerido para ''saltar'' el primer attrs
attrs.
La respuesta de Gingerhendrix cubre las bases, pero pensé que valía la pena explicar el método para pasar un valor de opciones para save
/ delete
/ fetch
.
En lugar de ensuciar su código con urls en cada lugar que llame a uno de esos métodos, también puede anular el método en su modelo en lugar de volver a delegar en el método Backbone.Model
original de esta manera:
var MyModel = Backbone.Model.extend({
save: function(attributes, options) {
options = _.defaults((options || {}), {url: "http://your.save.url.com/"});
return Backbone.Model.prototype.save.call(this, attributes, options);
},
// same thing for fetch and delete to give them different urls...
}
Luego, puede llamar al método en su código sin tener que preocuparse de recordar configurar la url
en las opciones.
Quiero borrar la respuesta de @gingerhendrix: puede pasar la URL a las opciones en guardar y irá directamente a la solicitud xhr (no es obvio desde la documentación o el código fuente o desde la respuesta, así que publico ot como una respuesta separada):
model.save({}, {url: ''/custom-url''});
Si estás leyendo la fuente, probablemente ya tengas una solución funcional. Básicamente tienes dos opciones (probablemente más) -
- Pase la URL en save () / fetch ()
save () toma dos parámetros attr y attr opciones - es un hash de atributos del modelo y se utiliza para actualizar el modelo antes de guardar. p.ej.
myModel.save(attrs)
es equivalente a
myModel.set(attrs)
myModel.save()
El segundo parámetro es un hash de opciones, que se pasa a this.sync () (y luego a Backbone.sync y luego a $ .ajax). Configurar el URL en este hash funcionará como se espera. Puede pasar falso, indefinido o {} como primer parámetro para omitir la actualización.
- Anular Backbone.sync
En lugar de tener url''s dispersos en todo su código cada vez que llame a save () o fetch () escriba su propia función de sincronización para calcular la url para usted, el delegado al Backbone.sync original para hacer el trabajo pesado
p.ej. (Esta función de sincronización agrega / guarda en la url en las acciones CREAR, ACTUALIZAR y ELIMINAR)
function mySyncFunction(method, model, options){
if(method==''GET''){
options.url = model.url;
}else{
options.url = model.url + ''/save'';
}
return Backbone.sync(method, model, options);
}
Para usar tu método de sincronización personalizado, solo debes declararlo como parte de tu modelo
var myModel = Backbone.Model.extend({
...
"sync": mySyncFunction,
...
});
Si tienes un modelo y una colección como:
MyModel = Backbone.Model.extend({
url: function(){ "API/"
return "API/MyModel/" +this.get("id");
}
});
MyCollection = Backbone.Collection.extend({
model: MyModel ,
url: "API/MyModels"
});
para recuperar la colección simplemente llame
MyCollection.fetch({
success: function(){
//do something here
},
error: function(){
//Handle your error
}
});
Para guardar su modelo, suponiendo que tiene el ID del modelo y ha instanciado su colección (llamándolo myCollection).
var model = myCollection .get(id);
model.save(
model.attributes,
{
success: function (model, response) {
//do something on success
},
error: function (model, response) {
//handle the error
}
}
);