7

我正在调用 ParentObject.doSomething() ,它又调用 WebService 对象来执行一些 ajax 调用,并且在 ajax 调用成功时,将执行回调函数。但是回调函数中的任何父函数都会失败。

我认为这与范围解析有关。我无法找到解决此问题的方法。

有没有更好的架构风格来模块化 ajax 服务和模型?

我还创建了一个 jsfiddle - http://jsfiddle.net/bzKXr/2/

var ParentObject =  {

     doSomething: function(){
         document.write("Inside doSomething <br />");
         var self = this;
         WebServices.firstService("some URL", self.successCallback);
     },

     changeData: function(data){
         //Manipulate data
         document.write("Inside changeData <br />");
     },

     successCallback: function(jsonData){
         document.write("Inside successCallback <br />");
         try {
             //Execution fails at this point. Possibly because of scope resolution
             this.changeData(jsonData);  
         }
         catch (error) {
             console.log(error);
             document.write(error);
         }  
     },
};

var WebServices = {
    firstService: function(url, successCallbackHandler){
        document.write("Inside firstService <br />");
        //Get data using the URL
        //on success call successCallback
        successCallbackHandler("some data");
    }
};


$(document).ready(function() {
    ParentObject.doSomething();

});
​
4

5 回答 5

11

编写self.successCallback不会将函数绑定到self,您必须实际调用函数self.successCallback()才能正确绑定上下文。

您可以通过将调用包装在保留访问权限的闭包中轻松做到这一点self

doSomething: function(){
     document.write("Inside doSomething <br />");
     var self = this;
     WebServices.firstService("some URL", function() {
        self.successCallback();
     });
 },

或者在 ES5 中,您可以使用.bind()which 确保this上下文successCallback始终是指定的参数:

doSomething: function(){
     document.write("Inside doSomething <br />");
     WebServices.firstService("some URL", this.successCallback.bind(this));
 },
于 2012-07-24T12:25:22.717 回答
2

这是最漂亮的方法:

WebServices.firstService("some URL", this.successCallback.bind( this ));

但是,它不是跨浏览器。(阅读:IE8及以下无法使用)

这就是为什么 jQuery 有$.proxy

WebServices.firstService("some URL", $.proxy( this.successCallback, this ));
于 2012-07-24T12:41:59.847 回答
1

调用回调函数时,this无效。在 javascript 中,如果使用 , 调用函数foo.bar()this将设置为foo,但如果您只调用,则将保留foo()先前设置,在您的情况下是事件的元素,可能是您的. 为避免这种情况,您必须使用闭包。您可以替换为。闭包意味着函数可以访问定义函数的范围内的变量,因此您的函数可以访问 ParenObject。thisWebServicethis.changeData(jsonData);ParentObject.changeData(jsonData);

更优雅的方式可能是:

var ParentObject =  {

    doSomething: function(){
        document.write("Inside doSomething <br />");
        var self = this;
        WebServices.firstService("some URL", function(jsonData) {
            document.write("Inside successCallback <br />");
            self.changeData(jsonData);
        }
    },

    changeData: function(data){
        //Manipulate data
        document.write("Inside changeData <br />");
    }
};

您的回调函数直接在您的doSomething函数中定义,因此您可以访问其中self定义的变量,并且可以调用self.changeData().

于 2012-07-24T12:33:58.217 回答
0

如果你改变this.changeData(jsonData);ParentObject.changeData(jsonData);应该工作。

错误的原因是该this变量不再引用ParentObjectAJAX 调用何时返回。

另一种方法是将引用存储this在另一个变量中(按照约定称为that)并更改您的代码以说that.changeData(jsonData);

于 2012-07-24T12:24:50.120 回答
0

另一种可能性是改变

WebServices.firstService("some URL", self.successCallback);

WebServices.firstService("some URL", function(data){ return self.successCallback(data) });

基本问题是,与 Python 不同,Javascript 中的方法 Javascript 一旦您将它们传递到其他地方或设置另一个变量,就会忘记它们的所有者对象。

于 2012-07-24T12:27:51.080 回答