How use setTimeout() with Backbone?

Asked By: Anonymous

How can I use setTimeout() in a Backbone model?
I have the next code:

var ContentModel = Backbone.Model.extend({
URL: "http://localhost/example.php",    
requestType: "POST",
dataType: "json",
data: "", //Set the value outside the model

startSend: function (Data) { 
           //
},
reply: function (Data) { 
    var dataJson = eval(Data);              
    console.log(dataJson);
    setTimeout(this.ajaxRequest(),4000);
},
problems: function (Data) { 
    //
},
ajaxRequest: function () {
    $.ajax({
        async:true,
        type: this.requestType,
        dataType: this.dataType, 
        url: this.URL,
        data: this.data,
        beforeSend:this.startSend,
        success: this.reply,
        timeout:4000,
        error:this.problems 
    });

}       

});

Alternatively I have tried:

setTimeout(function(){
               //ajax code
               },4000);

But the result is the same. setTimeout() don’t work. The request only run once.


Solution

Answered By: Anonymous

A couple of things are amiss. First off, this line:

setTimeout(this.ajaxRequest(),4000);

Should be:

setTimeout(this.ajaxRequest, 4000);

The first line of code executes the ajaxRequest function and passes the result (which is undefined) to setTimeout. That means the ajaxRequest function will execute once, but too soon. The latter line does what you want, which is to pass the function itself to setTimeout, and ajaxRequest will be called 4 seconds later.

But that’s not quite enough. When the ajaxRequest function is executed, the value of this context is incorrect. When you called setTimeout, the context of the callback is set to window. You can verify this by console.log(this) in the callback function.

To fix it, you need to bind the context of the function. Since you’re using Backbone, you’ve also got underscore.js already loaded. Using _.bind oughta do it:

setTimeout(_.bind(this.ajaxRequest, this), 4000);

Edit:

Come to think of it, there might be another problem. When the ajax call succeeds or fails, the reply or problems functions may suffer from the same loss of context as ajaxRequest did. But if there is, it’s easily fixed.

Instead of calling _.bind on those too, the simplest way is to call _.bindAll in your Backbone model constructor.

initialize: function() {
  _.bindAll(this, 'ajaxRequest', 'reply', 'problems');
}

When you call _.bindAll, underscore guarantees that every time any of the listed methods of your model is called, the this context variable points to the model itself, unless specifically bound to something else.

techinplanet staff

techinplanet staff


Windows 10 Kaufen Windows 10 Pro Office 2019 Kaufen Office 365 Lizenz Windows 10 Home Lizenz Office 2019 Home Business Kaufen windows office 365 satın al follower kaufen instagram follower kaufen porno