开发者

jQuery's AJAX call to a javascript class method

I'm a newbee about jQuery's workflow and I would like to setup a javascript class that uses an internal method to make an AJAX request. When the request returns with success, the jQuery AJAX callback should invoke a method owned by the class itself. That's the code:

function IXClock()
{
    this.m_intervalID = 0;

    this.startClock = function ()
    {
        this.m_intervalID = setInterval(this.tictac, 500);
    }

    this.stopClock = function ()
    {
        clearInterval(this.m_intervalID);
    }

    this.setClockTime = function(p_strTime)
    {
        $('#clock').html(p_strTime);
    }

    this.tictac = function ()
    {
        $.ajax
        ({
                type: 'POST',
                url: '/rap/rapClock.php',
                complete: function (data)
                {
                    this.setClockTime(data);
                }
        });
    }

}

The class represents a clock, with an internal method (tictac) that requests "what's the time" on the server side. After the server says the time, the jQuery's AJAX method should invoke the setClockTime method of the IXClock class. The invoke method will update the #clock div item in the html page.

The problem is that the method this.setClockTime() results unknown and the javascript return the "this.setClockTime is not a function" error.

The question is开发者_如何学运维: is there a way to invoka a class method from the jQuery's AJAX callback ?


I think that the problem is that the this in your callback function is different from the this referring to IXClock. Try:

var thisClass = this ;
this.tictac = function ()
{
    $.ajax
    ({
            type: 'POST',
            url: '/rap/rapClock.php',
            complete: function (data)
            {
                thisClass.setClockTime(data);
            }
    });
}

Test Case (added to site which already has jQuery loaded):

function uClass () {
    this.testFunction = function(input) {
        alert(input) ;
    }
    this.ajaxFunction = function() {
        var myClass = this ;
        $.ajax({
            type: 'POST',
            url: '/',
            complete: function(data) {
                alert(myClass.testFunction) ;
                myClass.testFunction(data) ;
                this.testFunction(data) ;
            }
        }) ;
    }
}

var k = new uClass() ;
k.ajaxFunction() ;


It happens bacause your callback function leave in global context.

You can choose 2 ways

  1. Use .bind function to bind context to callback function http://www.robertsosinski.com/2009/04/28/binding-scope-in-javascript/

  2. jQuery's AJAX supports transfer some data to callback function. You can write smth like this:

:

this.tictac = function () { $.ajax ({ type: 'POST', context:this, url: '/rap/rapClock.php', complete: function (data) { this.setClockTime(data); } }); }

}


this does not refer to IXClock in your ajax callback. this allways points to the current scope (have a look at this document). You need to do something like this:

this.prototype.tictac = function ()
{
    var self = this;
    $.ajax
    ({
        type: 'POST',
        url: '/rap/rapClock.php',
        complete: function (data)
        {
            self.setClockTime(data);
        }
    });
}

You can also use jQuery's .proxy()-function for this purpose:

this.prototype.tictac = function ()
{
    $.ajax
    ({
        type: 'POST',
        url: '/rap/rapClock.php',
        complete: $.proxy(function (data) {
            this.setClockTime(data);
        }, this)
    });
}


The this in the result handler is not what you expect it is. (It is not the IXClock instance)

function IXClock()
{
    this.m_intervalID = 0;
}

IXClock.prototype = {

    startClock: function ()
    {
        this.m_intervalID = setInterval(this.tictac, 500);
    },

    stopClock: function ()
    {
        clearInterval(this.m_intervalID);
    },

    setClockTime: function(p_strTime)
    {
        $('#clock').html(p_strTime);
    },

    tictac: function ()
    {
        var that = this;
        $.ajax({
            type: 'POST',
            url: '/rap/rapClock.php',
            success: function (data) { // You want success here, not complete, IMO
                that.setClockTime(data);
            }
        });
    }

}

If you ask me, that ajax call is doing evil. It does not seem to send any data, nor modify any state on the server, but is expecting/getting/using data from the php, yet is using the POST method. Should've been

$.get('/rap/rapClock.php', function (data) {
    that.setClockTime(data);
});


One simple solution is, to keep your callback function as self = this. This will support inheritance also.

class Record{
  get_data(){
    self = this;
    $.ajax({
        type : "GET",
        url : "/get_url",
        dataType : "json",
        contentType: "application/json; charset=utf-8",
        data : {},
        success : function(data){
          console.log(data);
          self.load_table(data);
        },
      });
  }

  static load_table(data){
    console.log(data);
  }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜