2012-04-05 10 views
3

Ich habe folgende Situation:Wie kann ein Backbone-Modell ein Ereignis von einem Ajax-Ergebnis auslösen?

var Task = Backbone.Model.extend({ 
    initialize: function() { 
    }, 
    save: function() { 
     $.ajax({ 
      type : "POST", 
      url  : "/api/savetask", 
      data : this.toJSON(), 
      success : function (response) { 
      this.trigger("something", "payload"); 
      } 
     }); 
    } 
}); 

Als ich das laufen lasse, erhalte ich die Fehlermeldung folgenden

this.trigger keine Funktion

Auf dem externen Ansatz ist, kann ich auslösen Zeug .. wie

var task = new Task(); 
task.trigger("something","payload"); 

Was mache ich falsch? oder nicht :)

Antwort

12

this in der anonymen Funktion bezieht sich auf das Ajax-Objekt. Dies liegt daran, dass sich "this" in Javascript in Bezug auf den Umfang der Funktion ändert. Um auf "dieses" der ursprünglichen Funktion zu verweisen, weisen Sie es einer anderen Variablen zu. Im Folgenden wird funktionieren:

save: function() { 
    var self = this; 
    $.ajax({ 
     type : "POST", 
     url  : "/api/savetask", 
     data : this.toJSON(), 
     success : function (response) { 
      self.trigger("something", "payload"); 
     } 
    }); 
} 

EDIT: Siehe an explanation, wie "dieses" bestimmt wird.

+0

Danke, funktioniert wie ein Charme. – DigitalWM

+0

andere Option wäre, dies an das zu binden, was Sie wollen, also _ (function (response) {...}). Bind (this) – OlliM

7

Persönlich bevorzuge ich eine saveSuccess Methode auf dem Modell.

+0

Wenn ich das versuche, ist 'this' in' saveSuccess' immer noch der XHR-Objekt und nicht das Modell. – AnalogWeapon

0

Dies ist eine sehr späte Antwort, aber falls jemand anderes auf dieser Seite passiert: Es gibt einen viel besseren Weg. Die Verwendung des Self-Objekts (meiner Erfahrung nach) wird als ein kleines Anti-Pattern betrachtet, da wir die Funktion underscore.js verwenden und Zugriff auf die bind-Funktion haben. Wie auch immer, hier ist eine bessere Art und Weise:

var Task = Backbone.Model.extend({ 
    initialize: function() { 
    }, 
    save: function() { 
     $.ajax("/api/savetask", { 
      type : "POST", 
      data : this.toJSON(), 
      context : this, 
      success : function (response) { 
       this.trigger("something", "payload"); 
      } 
     }); 
    } 
}); 

Es kann der Fall sein, dass das context Attribut wurde in einer aktuellen Version von jQuery hinzugefügt, und es war vor nicht zur Verfügung. Aber das ist (meiner Meinung nach) der beste Weg, dies zu tun.

Verwandte Themen