2012-04-18 15 views
19

Estoy tratando con una colección de comentarios enhebrados, y cuando elimino un comentario que tiene hijos, hago model.destroy() para este comentario, y en el lado del servidor se borran todas sus ramas.Backbone JS: ¿cómo desactivar la sincronización para eliminar?

Escribí una función que una vez que un nodo se elimina del árbol, busca a todos los huérfanos y los elimina también. Así que cuando encuentro huérfanos, ejecuto model.destroy() en ellos también, pero como ya están eliminados en el servidor, la sincronización devuelve errores.

¿Hay alguna forma de deshabilitar la sincronización para algunas llamadas al destroy()?

+0

Tengo curiosidad si anular '.sync()' y agregar alguna lógica extra para el método 'delete' sería excesivo para esto, o si hay una manera más clara. –

+0

Bueno, esperaba NO anular .sync() Pero no puedo ver ninguna forma nativa de hacerlo. Puedo hackear desencadenando eventos 'destruir' y empalmando el modelo de la colección, pero eso no suena kosher. –

Respuesta

31

Dado que todo el método destroy hace es enviar una petición DELETE y desencadena destroy, simplemente desencadenar destroyes exactamente lo que estás buscando.

model.trigger('destroy', model, model.collection, options); 

Sí, se siente un poco hackish, pero eso es todo lo que hace el código Backbone. Si lo desea, y si tiene un modelo base desde el cual extenderse, podría agregarlo como un método en ese modelo base, y podría no sentirse tan hambriento.

+0

Gracias @Edward. Terminé simplemente eliminándolos de la colección. –

+8

'' 'model.collection.remove (model);' '' funciona. – forresto

+4

@forresto - eso funciona si el modelo está solo en una sola colección. Si tiene el modelo de varias colecciones, debe saber en qué colecciones está el modelo y hacerlo en cada colección, lo que significa hacer un seguimiento en el modelo a qué colecciones pertenece. Eso es un poco al revés. Al activar 'destruir' en el modelo, cualquier colección en la que se encuentre se eliminará, y usted no tiene que rastrear en qué colecciones se encuentra el modelo. –

2

Esto es un poco tarde pero podría funcionar como una solución alternativa para otras personas que tienen el mismo problema.

Enfrentado con un problema muy similar, terminé configurando todos los ID de niños a null antes de llamar al destroy en ellos. De esta forma, la red troncal cree que son new y no generan una solicitud HTTP DELETE al servidor al momento de la eliminación.

deleteParent: function() { 
    this.model.children.each(function(child) { 
    // Set to null so that it doesn't try to spawn a 'DELETE' http request 
    // on 'destroy' since thinks its new (hack). 
    child.id = null; 
    child.destroy(); 
    }); 
    // This one DOES result in a 'DELETE' http request since it has an ID. 
    this.model.destroy(); 
}, 
+0

Bueno, entonces, ¿cuál sería el propósito de destruir sin eliminar realmente del servidor? –

+0

Si entendí su pregunta correctamente, cuando eliminó el elemento primario del servidor, también eliminó todos sus elementos secundarios (tal vez en una transacción), por lo que cuando elimina (* destruye *) a los niños huérfanos de la interfaz de usuario que no desea para hacer una llamada al servidor para eliminar a cada uno de los huérfanos ya que ya no existen. Esto logra el comportamiento deseado. – fcarriedo

1

Se encontró con este mismo problema.

Usando el enlace del modelo a su colección que contiene para eliminar el modelo de esa colección fue mi solución preferida, ya que esto era exactamente lo que quería hacer y muy claro en el código:

// From the view 
this.model.collection.remove(this.model); 
+0

Aunque esto elimina el modelo de la colección, esto no desencadenará el evento de destrucción que puede causar problemas si tiene un evento que lo escuche. –

1

Sobre la base de la respuesta de fcarriedo , simplemente reemplazar el método destruir en la declaración de su modelo:

Models.YourModelName = Backbone.Model.extend({ 
    destroy: function() { 
     this.id = null; 
     Backbone.Model.prototype.destroy.apply(this, arguments); 
    } 
}); 
2

Esto permite que respeten la llamada destruir, incluyendo cualquier controlador de éxito

Backbone.Model.extend({ 
    destroy: function (options) { 
     // don't make a server call, just delete from collection and call success 
     this.trigger('destroy', this, this.collection, options); 
     if (options && options.success) { 
       options.success(); 
     } 
    } 
}); 
Cuestiones relacionadas