是否有一种方法可以在jQuery中传递更多的数据到回调函数?

我有两个函数,我想回调到$。例如,使用post来传递AJAX调用的结果数据和一些自定义参数

function clicked() {
    var myDiv = $("#my-div");
    // ERROR: Says data not defined
    $.post("someurl.php",someData,doSomething(data, myDiv),"json"); 
    // ERROR: Would pass in myDiv as curData (wrong)
    $.post("someurl.php",someData,doSomething(data, myDiv),"json"); 
}

function doSomething(curData, curDiv) {

}

我希望能够将自己的参数传递给回调,以及从AJAX调用返回的结果。


当前回答

作为b01的答案的补充,$的第二个参数。代理通常用于保存this引用。附加参数传递给$。代理部分应用于函数,用数据预填充它。注意任何参数$.;传递给回调函数的post函数将在最后被应用,所以doSomething函数的参数列表末尾应该有这些参数:

function clicked() {
    var myDiv = $("#my-div");
    var callback = $.proxy(doSomething, this, myDiv);
    $.post("someurl.php",someData,callback,"json"); 
}

function doSomething(curDiv, curData) {
    //"this" still refers to the same "this" as clicked()
    var serverResponse = curData;
}

这种方法还允许将多个参数绑定到回调:

function clicked() {
    var myDiv = $("#my-div");
    var mySpan = $("#my-span");
    var isActive = true;
    var callback = $.proxy(doSomething, this, myDiv, mySpan, isActive);
    $.post("someurl.php",someData,callback,"json"); 
}

function doSomething(curDiv, curSpan, curIsActive, curData) {
    //"this" still refers to the same "this" as clicked()
    var serverResponse = curData;
}

其他回答

如果还有人来这里,我的看法是:

$('.selector').click(myCallbackFunction.bind({var1: 'hello', var2: 'world'}));

function myCallbackFunction(event) {
    var passedArg1 = this.var1,
        passedArg2 = this.var2
}

这里发生了什么,绑定回调函数后,它将在函数中像这样可用。

这个想法来自React如何使用绑定功能。

解决方案是通过闭包绑定变量。


作为一个更基本的例子,这里有一个接收和调用回调函数的例子函数,以及一个回调函数的例子:

function callbackReceiver(callback) {
    callback("Hello World");
}

function callback(value1, value2) {
    console.log(value1, value2);
}

这将调用回调函数并提供一个参数。现在你想要提供一个额外的参数,所以你用闭包包装回调。

callbackReceiver(callback);     // "Hello World", undefined
callbackReceiver(function(value) {
    callback(value, "Foo Bar"); // "Hello World", "Foo Bar"
});

或者,更简单地使用ES6箭头函数:

callbackReceiver(value => callback(value, "Foo Bar")); // "Hello World", "Foo Bar"

至于你的具体例子,我没有在jQuery中使用过.post函数,但快速扫描文档建议回调应该是一个具有以下签名的函数指针:

function callBack(data, textStatus, jqXHR) {};

因此我认为解决方法如下:

var doSomething = function(extraStuff) {
    return function(data, textStatus, jqXHR) {
        // do something with extraStuff
    };
};

var clicked = function() {
    var extraStuff = {
        myParam1: 'foo',
        myParam2: 'bar'
    }; // an object / whatever extra params you wish to pass.

    $.post("someurl.php", someData, doSomething(extraStuff), "json");
};

发生了什么?

在最后一行中,调用doSomething(extrastutff),调用的结果是一个函数指针。

因为extraStuff是作为参数传递给doSomething的,所以它在doSomething函数的范围内。

当在返回的匿名内部函数doSomething中引用extraStuff时,它通过闭包绑定到外部函数的extraStuff参数。即使在doSomething返回之后也是如此。

我还没有对上面的代码进行测试,但我在过去24小时内编写了非常类似的代码,它的工作原理正如我所描述的那样。

当然,你可以传递多个变量,而不是一个“extraStuff”对象,这取决于你的个人偏好/编码标准。

你可以使用JavaScript的闭包:

function wrapper( var1, var2,....) // put here your variables
{
  return function( data, status)
  {
     //Handle here results of call
  }
};

当你可以这样做时:

$.post("someurl.php",data,wrapper(var1, var2, etc...),"html");

对于我和其他刚接触Javascript的新手来说, 我认为Closeure解决方案有点太混乱了。

虽然我发现,你可以很容易地传递尽可能多的参数,因为你想每个ajax回调使用jquery。

这里有两个更简单的解决方案。

第一个,@zeroasterisk在上面提到过,例子:

var $items = $('.some_class');
$.each($items, function(key, item){
    var url = 'http://request_with_params' + $(item).html();
    $.ajax({
        selfDom     : $(item),
        selfData    : 'here is my self defined data',

        url         : url,
        dataType    : 'json',
        success     : function(data, code, jqXHR){
            // in $.ajax callbacks, 
            // [this] keyword references to the options you gived to $.ajax
            // if you had not specified the context of $.ajax callbacks.
            // see http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings context
            var $item = this.selfDom;
            var selfdata = this.selfData;
            $item.html( selfdata );
            ...
        } 
    });
});

第二步,通过将自定义数据添加到XHR对象中来传递这些数据 它存在于整个ajax请求-响应生命周期中。

var $items = $('.some_class');
$.each($items, function(key, item){
    var url = 'http://request_with_params' + $(item).html();
    $.ajax({
        url         : url,
        dataType    : 'json',
        beforeSend  : function(XHR) {
            // 为了便于回调,把当前的 jquery对象集存入本次 XHR
            XHR.selfDom = $(item);
            XHR.selfData = 'here is my self defined data';
        },
        success     : function(data, code, jqXHR){
            // jqXHR is a superset of the browser's native XHR object
            var $item = jqXHR.selfDom;
            var selfdata = jqXHR.selfData;
            $item.html( selfdata );
            ...
        } 
    });
});

正如你所看到的,这两种解决方案都有一个缺点:你每次都需要多写一些代码,而不仅仅是写:

$.get/post (url, data, successHandler);

阅读更多关于$的信息。Ajax: http://api.jquery.com/jquery.ajax/

让我们简单点!:)

$.ajax({
    url: myUrl,
    context: $this, // $this == Current $element
    success: function(data) {
        $.proxy(publicMethods.update, this)(data); // this == Current $element
    }
});