JQuery AJAX和OOP JS范围问题

时间:2021-04-25 13:32:30

So, I created an object which makes an AJAX call to populate its properties during the initialization phase. However, I am running into a very weird behaviour: I can print and see the property values fine within the $.ajax() scope, but any public method that returns the value of properties have a return value of "undefined".

因此,我创建了一个对象,该对象在初始化阶段进行AJAX调用以填充其属性。但是,我遇到了一个非常奇怪的行为:我可以在$ .ajax()范围内打印并查看属性值,但是返回属性值的任何公共方法都返回值为“undefined”。

Here's what the JS code looks like:

这是JS代码的样子:

function MyFunction() {
   this.myProperty;
   this.init();
}

Myfunction.prototype.getPropertyValue = function () {
    alert(this.myProperty); // returns 'undefined'
}

Myfunction.prototype.init = function () { 
   $.ajax({
      type: 'get',
      url: "getProperty.php",
      dataType: "json",
      success: function(response) {
         this.myProperty = response[0].Property;
         alert(this.myProperty) // returns 'Property Name'
      }
   });
}

My thinking is that within the $.ajax() scope, 'this' is actually referring to something else. So, my question is how do I make sure that 'this.myProperty' is set and doesn't lose its value once we get outside of the AJAX scope?

我的想法是在$ .ajax()范围内,'this'实际上指的是其他东西。所以,我的问题是如何确保设置'this.myProperty'并且一旦我们超出AJAX范围就不会失去它的价值?

Any help is much appreciated.

任何帮助深表感谢。

3 个解决方案

#1


4  

Part of the reason why you're getting "undefined" because of the way you establish the value:

由于您建立值的方式,您获得“未定义”的部分原因:

var MyFunction = function () {
   this.myProperty;
   alert(this.myProperty); // undefined!
   this.init();
};

When you declare properties (or variables) without specifying a value, they default to "undefined". Instead:

在未指定值的情况下声明属性(或变量)时,它们默认为“undefined”。代替:

var MyFunction = function () {
   this.myProperty = false;
   alert(this.myProperty); // false
   this.init();
};

On to the ajax call. You are right that the scope of the callback is not the same as the object. this, in the ajax success function, refers to the jQuery-wrapped XHR object. When you call this.myProperty = response[0].Property, you are actually creating a new property on the ajax object and setting its value. To correct this, you can either use the context option of the jQuery ajax object, OR bind the callback function using the javascript bind method:

关于ajax调用。你是对的,回调的范围与对象不同。这个,在ajax成功函数中,指的是jQuery包装的XHR对象。当你调用this.myProperty = response [0] .Property时,你实际上是在ajax对象上创建一个新属性并设置它的值。要解决此问题,您可以使用jQuery ajax对象的context选项,也可以使用javascript bind方法绑定回调函数:

  success: function(response) {
     this.myProperty = response[0].Property;
  }.bind(this)

... or:

   $.ajax({
      type: 'get',
      url: "getProperty.php",
      dataType: "json",
      context: this,
      success: function(response) {
         this.myProperty = response[0].Property;
      }
   });

Try it here: http://jsfiddle.net/SnLmu/

在这里试试:http://jsfiddle.net/SnLmu/

Documentation

#2


0  

Part of the problem is that the ajax is asynchronous so the properties may not be set when you try to access them (race condition). The other is the value of this inside of the ajax call is not Myfunction. You can fix by:

部分问题是ajax是异步的,因此当您尝试访问它们时,可能无法设置属性(竞争条件)。另一个是这个ajax调用里面的值不是Myfunction。您可以修复:

Myfunction.prototype.init = function () { 
   var that = this;
   $.ajax({
      type: 'get',
      url: "getProperty.php",
      dataType: "json",
      success: function(response) {
         that.myProperty = response[0].Property;
         alert(that.myProperty) // returns 'Property Name'
      }
   });
}

or you can use the context setting in the ajax call. Per the site:

或者您可以使用ajax调用中的上下文设置。每个网站:

This object will be made the context of all Ajax-related callbacks. By default, the context is an object that represents the ajax settings used in the call ($.ajaxSettings merged with the settings passed to $.ajax). For example, specifying a DOM element as the context will make that the context for the complete callback of a request, like so:

此对象将成为所有与Ajax相关的回调的上下文。默认情况下,上下文是一个对象,表示调用中使用的ajax设置($ .ajaxSettings与传递给$ .ajax的设置合并)。例如,将DOM元素指定为上下文将使得请求的完整回调的上下文,如下所示:

Myfunction.prototype.init = function () { 
       var that = this;
       $.ajax({
          type: 'get',
          url: "getProperty.php",
          dataType: "json",
          context: Myfunction,
          success: function(response) {
             this.myProperty = response[0].Property;
             alert(this.myProperty) // returns 'Property Name'
          }
       });
    }

#3


0  

var MyFunction = {
    myProperty: null,
    init: function() {
        var self = this;
        self.ajax(function(response) {
            self.myProperty = response;
            self.secondfunction(self.myProperty); //call next step only when ajax is complete
        });
    },
    ajax: function(callback) {
        $.ajax({
            type: 'get',
            url: "getProperty.php",
            dataType: "json"
        }).done(function(response) {
            callback(response[0].Property);
        });
    },
    secondfunction: function(prop) {
        alert(prop);
    }
}

$(function() {    
    MyFunction.init();
});

#1


4  

Part of the reason why you're getting "undefined" because of the way you establish the value:

由于您建立值的方式,您获得“未定义”的部分原因:

var MyFunction = function () {
   this.myProperty;
   alert(this.myProperty); // undefined!
   this.init();
};

When you declare properties (or variables) without specifying a value, they default to "undefined". Instead:

在未指定值的情况下声明属性(或变量)时,它们默认为“undefined”。代替:

var MyFunction = function () {
   this.myProperty = false;
   alert(this.myProperty); // false
   this.init();
};

On to the ajax call. You are right that the scope of the callback is not the same as the object. this, in the ajax success function, refers to the jQuery-wrapped XHR object. When you call this.myProperty = response[0].Property, you are actually creating a new property on the ajax object and setting its value. To correct this, you can either use the context option of the jQuery ajax object, OR bind the callback function using the javascript bind method:

关于ajax调用。你是对的,回调的范围与对象不同。这个,在ajax成功函数中,指的是jQuery包装的XHR对象。当你调用this.myProperty = response [0] .Property时,你实际上是在ajax对象上创建一个新属性并设置它的值。要解决此问题,您可以使用jQuery ajax对象的context选项,也可以使用javascript bind方法绑定回调函数:

  success: function(response) {
     this.myProperty = response[0].Property;
  }.bind(this)

... or:

   $.ajax({
      type: 'get',
      url: "getProperty.php",
      dataType: "json",
      context: this,
      success: function(response) {
         this.myProperty = response[0].Property;
      }
   });

Try it here: http://jsfiddle.net/SnLmu/

在这里试试:http://jsfiddle.net/SnLmu/

Documentation

#2


0  

Part of the problem is that the ajax is asynchronous so the properties may not be set when you try to access them (race condition). The other is the value of this inside of the ajax call is not Myfunction. You can fix by:

部分问题是ajax是异步的,因此当您尝试访问它们时,可能无法设置属性(竞争条件)。另一个是这个ajax调用里面的值不是Myfunction。您可以修复:

Myfunction.prototype.init = function () { 
   var that = this;
   $.ajax({
      type: 'get',
      url: "getProperty.php",
      dataType: "json",
      success: function(response) {
         that.myProperty = response[0].Property;
         alert(that.myProperty) // returns 'Property Name'
      }
   });
}

or you can use the context setting in the ajax call. Per the site:

或者您可以使用ajax调用中的上下文设置。每个网站:

This object will be made the context of all Ajax-related callbacks. By default, the context is an object that represents the ajax settings used in the call ($.ajaxSettings merged with the settings passed to $.ajax). For example, specifying a DOM element as the context will make that the context for the complete callback of a request, like so:

此对象将成为所有与Ajax相关的回调的上下文。默认情况下,上下文是一个对象,表示调用中使用的ajax设置($ .ajaxSettings与传递给$ .ajax的设置合并)。例如,将DOM元素指定为上下文将使得请求的完整回调的上下文,如下所示:

Myfunction.prototype.init = function () { 
       var that = this;
       $.ajax({
          type: 'get',
          url: "getProperty.php",
          dataType: "json",
          context: Myfunction,
          success: function(response) {
             this.myProperty = response[0].Property;
             alert(this.myProperty) // returns 'Property Name'
          }
       });
    }

#3


0  

var MyFunction = {
    myProperty: null,
    init: function() {
        var self = this;
        self.ajax(function(response) {
            self.myProperty = response;
            self.secondfunction(self.myProperty); //call next step only when ajax is complete
        });
    },
    ajax: function(callback) {
        $.ajax({
            type: 'get',
            url: "getProperty.php",
            dataType: "json"
        }).done(function(response) {
            callback(response[0].Property);
        });
    },
    secondfunction: function(prop) {
        alert(prop);
    }
}

$(function() {    
    MyFunction.init();
});