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
¿Fue útil?

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top