How can the underlying model trigger an event from an Ajax result?

I have the following situation:

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

      

When I run this I get the following error

this.trigger

not a function

In an external approach, I can call something like.

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

      

What am I doing wrong? or doesn't :)

+3


source to share


3 answers


this

in anonymous function refers to an ajax object. This is because "this" in javascript changes with respect to the scope of the function. To refer to "this" in the original function, assign it to another variable. The following will work:

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

      



EDIT: See the explanation on how "this" is defined.

+12


source


I personally prefer to have a method saveSuccess

on the model.



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

      

+7


source


This is a very late answer, but in case anyone else happens on this page: there is a much better way. Using self-object is (in my experience) considered a bit anti-pattern since we are using underscore.js and have access to the function bind

. Anyway, here's the best way:

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

      

Maybe the attribute context

was added in a recent version of jQuery and wasn't available before. But this is (in my opinion) the best way to do it.

0


source







All Articles