Backbone Model.destroy () Invocar la función de devolución de llamada de error incluso cuando funciona bien?
Pregunta
tengo un Backbone.js Modelo que estoy tratando de destruir cuando el usuario hace clic en un enlace en la vista del modelo. La vista es algo como esto (pseudocódigo porque se implementa en Cafetería que se puede encontrar en la parte inferior de la pregunta).
var window.ListingSaveView = Backbone.View.extend({
events: {
'click a.delete': 'onDestroy'
},
onDestroy: function(event){
event.preventDefault();
this.model.destroy({
success: function(model, response){
console.log "Success";
},
error: function(model, response){
console.log "Error";
}
});
}
});
Cuando hago clic en el delete
enlace en el navegador, siempre obtengo Error
iniciado sesión en la consola a pesar de que mi servidor registra la destrucción exitosa del registro de la base de datos asociada y devuelve una respuesta de 200. Cuando actualice la página (que hace que la colección vuelva a renderizar desde el DB), el modelo que eliminé se habrá ido.
Una interesante esto es que cuando registro el response
En la devolución de llamada de error, tiene estado de estado 200
indicando éxito pero también informa statusText: "parseerror"
Lo que sea que eso signifique. No hay error en mis registros de servidor.
¿Qué estoy haciendo mal?
Esta es la respuesta del servidor:
Object
abort: function ( statusText ) {
always: function () {
complete: function () {
done: function () {
error: function () {
fail: function () {
getAllResponseHeaders: function () {
getResponseHeader: function ( key ) {
isRejected: function () {
isResolved: function () {
overrideMimeType: function ( type ) {
pipe: function ( fnDone, fnFail ) {
promise: function ( obj ) {
readyState: 4
responseText: " "
setRequestHeader: function ( name, value ) {
status: 200
statusCode: function ( map ) {
statusText: "parsererror"
success: function () {
then: function ( doneCallbacks, failCallbacks ) {
__proto__: Object
Aquí está la acción del servidor que destruye interactúa con (Ruby on Rails)
# DELETE /team/listing_saves/1.json
def destroy
@save = current_user.team.listing_saves.find(params[:id])
@save.destroy
respond_to do |format|
format.json { head :ok }
end
end
Y aquí está la implementación real de cafees de la visión de la columna vertebral para las personas que la prefieren así:
class MoveOutOrg.Views.ListingSaveView extends Backbone.View
tagName: 'li'
className: 'listing_save'
template: JST['backbone/templates/listing_save']
events:
'click a.delete_saved': 'onDestroy'
initialize: ->
@model.bind 'change', this.render
render: =>
renderedContent = @template(@model.toJSON())
$(@el).html(renderedContent)
this
onDestroy: (event) ->
event.preventDefault() # stop the hash being added to the URL
console.log "Listing Destroyed"
@model.destroy
success: (model, response)->
console.log "Success"
console.log model
console.log response
error: (model, response) ->
console.log "Error"
console.log model # this is the ListingSave model
console.log response
Solución
@David Tuite Comentario:
"Ok, lo descubrí. Parece que Backbone espera que la respuesta JSON sea una serialización JSON del registro que fue destruido. Sin embargo, los generadores de controladores de Rails solo devuelven la cabeza: OK por defecto. Cambié mi respuesta JSON para que Rendere JSON: @Listing_Save donde @listing_save es el registro que acabo de destruir y registra un éxito ".
FYI - Cuando estás destruyendo, no necesitas devolver el JSON completo para el modelo destruido. Puedes devolver un hash JSON vacío y funcionará bien. El único momento que necesita para devolver el JSON para el modelo está en una guardia / actualización.
Otros consejos
Yo tuve el mísmo problema. En mi método Eliminar en el servidor (Java), no devolví nada. Simplemente estado 200/OK (o 204/sin contenido). Y así, el problema de "ParserError" fue causado por JQuery tratando de convertir la respuesta vacía en JSON, que falló (ya que "JSON" es el tipo de datos predeterminado).
Mi solución era usar el tipo de datos "Texto", que se puede configurar en las opciones:
model.destroy({ dataType: "text", success: function(model, response) {
console.log("success");
}});
Su respuesta debe tener el código de estado 204, ya que no devolverá ningún contenido. Dado que Backbone utiliza una interfaz REST, debe devolver diferentes códigos de estado HTTP según la tarea.
¿Estás seguro de tu URL? ¿Agregas un .json
Al final de la columna vertebral. Dado que verifica esto en el lado de su servidor (responde_to hacer | formato | ... final), es posible que no envíe lo correcto head :ok
respuesta
Intenta con esto destroy
Método de rieles para probar si este es el problema:
def destroy
@save = current_user.team.listing_saves.find(params[:id])
@save.destroy
head :ok
end
Usando el marco delgado en un servidor de lámparas, puede agregar un Estado de respuesta a ELIMINAR rutas (o rutas personalizadas que no devuelven nada)
$app->response()->status(204);//204 No Content
Esto también establece el tipo de contenido de nuevo en texto/html para permitir el cuerpo vacío