36 votes

Backbone model.destroy () invoquant la fonction de rappel d'erreur même quand cela fonctionne bien?

J'ai un Backbone.js le modèle que je suis en train de détruire lorsque l'utilisateur clique sur un lien dans le modèle de vue. La vue est quelque chose comme ceci (pseudocode parce qu'il est mis en œuvre en CoffeeScript qui peut être trouvé au bas de la question).

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";
      }
    });
  }
});

Lorsque je clique sur l' delete lien dans le navigateur, j'ai toujours Error connecté à la console, même si mes enregistrements de serveur de succès de la destruction de l'enregistrement de base de données et renvoie une réponse 200. Lorsque j'actualise la page (provoquant de la collection, afin de rendre à nouveau à partir de la DB), le modèle que j'ai supprimé aura disparu.

Un intéressant c'est que lorsque je connecte l' response dans l'erreur de rappel, il a statuscode 200 indiquant la réussite mais aussi les rapports d' statusText: "parseerror" quoi que cela signifie. Il n'y a pas d'erreur dans mes logs du serveur.

Ce que je fais mal?

C'est la réponse du serveur:

  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

Ici, c'est le serveur d'action qui détruisent interagit avec (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

Et ici, c'est le réel CoffeeScript mise en œuvre de l'épine Dorsale de la Vue pour les personnes qui le préfère comme ça:

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

52voto

Derick Bailey Points 37859

@David Tuite commentaire:

"Ok j'ai tout compris. Il semble que l'épine Dorsale attend la réponse JSON pour être une sérialisation JSON de l'enregistrement qui a été détruit. Cependant, les Rails contrôleur de générateurs seulement revenir la tête :ok par défaut. J'ai changé ma réponse JSON pour être rendu json: @listing_save où @listing_save est l'album que j'ai détruit et elle enregistre un succès."

FYI - lorsque vous faites détruire, vous n'avez pas besoin de retourner la totalité json pour la destruction de modèle. vous pouvez nous retourner un vide json de hachage et il fonctionne très bien. le seul moment où vous devez retourner le json pour le modèle est sur enregistrer / mettre à jour.

16voto

ccallendar Points 596

J'ai eu le même problème. Dans ma méthode de suppression sur le serveur (java), je n’ai rien renvoyé. Juste le statut 200 / OK (ou 204 / Pas de contenu). Et donc le problème de "parsererror" a été causé par jquery essayant de convertir la réponse vide en JSON, ce qui a échoué (puisque "json" est le type de données par défaut).

Ma solution consistait à utiliser le type de texte "text", qui peut être défini dans les options:

 model.destroy({ dataType: "text", success: function(model, response) {
  console.log("success");
}});
 

7voto

David Rios Points 71

Votre réponse doit avoir le code de statut 204 car vous ne retournerez aucun contenu. Le backbone utilisant une interface REST, vous devez renvoyer différents codes d’état http en fonction de la tâche.

0voto

Tricote Points 926

Êtes-vous sûr de votre URL? Ajoutez-vous un .json à la fin de l’URL Backbone.Model? Puisque vous vérifiez ceci sur votre serveur (respond_to do | format | ... end), vous risquez de ne pas envoyer la bonne réponse head :ok

Essayez avec cette méthode destroy rails de vérifier si tel est le problème:

 def destroy
  @save = current_user.team.listing_saves.find(params[:id])
  @save.destroy
  head :ok
end
 

0voto

mhume Points 1

En utilisant le Slim Framework sur un serveur LAMP, vous pouvez ajouter un état de réponse aux itinéraires DELETE (ou des itinéraires personnalisés qui ne renvoient rien).

$app->response()->status(204);//204 No Content

cela redéfinit également le type de contenu sur text / html afin de permettre au corps vide

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X