jQuery passere flere parametre i tilbakeringing

stemmer
245

Er det en måte å passere mer data inn i en tilbakeringingsfunksjonen i jQuery?

Jeg har to funksjoner, og jeg vil at tilbakeringing til $.post, for eksempel, å passere i både den resulterende data av AJAX samtalen, samt noen få tilpasset argumenter

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) {

}

Jeg ønsker å være i stand til å passere i mine egne parametre på en tilbakeringings, samt resultatet returnert fra AJAX samtalen.

Publisert på 02/06/2009 klokken 11:35
kilden bruker
På andre språk...                            


14 svar

stemmer
0

faktisk, er koden ikke fungerer fordi når du skriver:

$.post("someurl.php",someData,doSomething(data, myDiv),"json"); 

du plasserer et funksjonskall som den tredje parameter i stedet for en funksjonsreferansen .

Svarte 02/06/2009 kl. 11:53
kilden bruker

stemmer
7

Du kan også prøve noe som følgende:

function clicked() {

    var myDiv = $("#my-div");

    $.post("someurl.php",someData,function(data){
        doSomething(data, myDiv);
    },"json"); 
}

function doSomething(curData, curDiv) {

}
Svarte 02/06/2009 kl. 12:04
kilden bruker

stemmer
79

Når du bruker doSomething(data, myDiv), du faktisk kaller funksjonen og ikke gjøre en referanse til det.

Du kan enten bestå doStomethingfunksjon direkte, men du må sørge for at den har riktig signatur.

Hvis du ønsker å holde doSomething slik det er, kan du pakke sin samtale i en anonym funksjon.

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

function doSomething(curData, curDiv) {
    ...
}

Inne i anonym funksjon koden, kan du bruke variablene definert i omsluttende omfang. Dette er måten Javascript scoping fungerer.

Svarte 02/06/2009 kl. 12:05
kilden bruker

stemmer
5

Du kan bruke en nedleggelse av Javascript:

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

og når du kan gjøre:

$.post("someurl.php",data,wrapper(var1, var2, etc...),"html");
Svarte 02/06/2009 kl. 12:13
kilden bruker

stemmer
329

Løsningen er bindingen av variablene gjennom lukningen.


Som en mer grunnleggende eksempel, her er et eksempel funksjon som mottar og kaller en tilbakeringingsfunksjonen, samt et eksempel tilbakering funksjon:

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

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

Dette kaller tilbakeringing og leverer et enkelt argument. Nå vil du levere et ekstra argument, slik at du vikle tilbakeringing i nedleggelse.

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

Eller ganske enkelt ved hjelp ES6 Arrow Funksjoner :

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

Som for konkret eksempel, har jeg ikke brukt .postfunksjon i jQuery, men en rask skanning av dokumentasjonen tyder på anropet tilbake bør være en funksjonspeker med følgende signatur:

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

Derfor tror jeg løsningen er som følger:

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");
};

Hva skjer?

I den siste linjen, doSomething(extraStuff)blir påkalt og resultatet av dette påkalling er en funksjon peker .

Fordi extraStuffføres som et argument til doSomethingdet er innenfor rammen av doSomethingfunksjon.

Når extraStuffdet refereres til i returneres anonym indre funksjon av doSomethingden er bundet av lukningen til den ytre funksjonens extraStuffargument. Dette gjelder også etter at doSomethinghar kommet tilbake.

Jeg har ikke testet den over, men jeg har skrevet svært lik kode i de siste 24 timene, og det fungerer som jeg har beskrevet.

Du kan selvsagt passere flere variabler i stedet for en enkelt 'extraStuff' objekt avhengig av personlige preferanser / koding standarder.

Svarte 02/06/2009 kl. 12:18
kilden bruker

stemmer
3

Jeg har gjort en feil i det siste innlegget mitt. Dette er arbeider eksempel på hvordan å passere ekstra argument i tilbakering funksjon:

function custom_func(p1,p2) {
    $.post(AJAX_FILE_PATH,{op:'dosomething',p1:p1},
        function(data){
            return function(){
                alert(data);
                alert(p2);
            }(data,p2)
        }
    );
    return false;
}
Svarte 03/09/2010 kl. 15:25
kilden bruker

stemmer
18

I dagens verden er det et annet svar som er renere, og tatt fra en annen Stack Overflow svar:

function clicked()
{
    var myDiv = $( "#my-div" );

    $.post( "someurl.php", {"someData": someData}, $.proxy(doSomething, myDiv), "json" );
}

function doSomething( data )
{
    // this will be equal to myDiv now. Thanks to jQuery.proxy().
    var $myDiv = this;

    // doing stuff.
    ...
}

Her er det opprinnelige spørsmålet og svaret: jQuery HVORDAN ?? tilleggsparametere til suksess tilbakeringing for $ .ajax samtale?

Svarte 08/09/2011 kl. 15:48
kilden bruker

stemmer
0

Som et tillegg til B01 svar , den andre argumentet $.proxyblir ofte brukt for å bevare thisreferanse. Ytterligere argumenter som sendes til $.proxysom delvis er påført denne funksjon er det bare fylle den med data. Merk at noen argumenter $.postgår til tilbakeringing vil bli brukt på slutten, så doSomethingbør ha de på slutten av sin argumentliste:

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;
}

Denne tilnærmingen gjør også flere argumenter for å være bundet til tilbakeringing:

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;
}
Svarte 08/10/2011 kl. 18:06
kilden bruker

stemmer
49

Det er faktisk lettere enn alle er å gjøre det høres ... spesielt hvis du bruker $.ajax({})basen syntaks kontra en av hjelpefunksjoner.

Bare pass på key: valueparet som du ville gjort på et objekt, når du sette opp din Ajax forespørselen ... (fordi $(this)ikke har endret sammenheng ennå, er det fortsatt den trigger for bind samtalen ovenfor)

<script type="text/javascript">
$(".qty input").bind("keypress change", function() {
    $.ajax({
        url: "/order_items/change/"+$(this).attr("data-order-item-id")+"/qty:"+$(this).val()+"/returnas.json",
        type: "POST",
        dataType: "json",
        qty_input: $(this),
        anything_else_i_want_to_pass_in: "foo",
        success: function(json_data, textStatus, jqXHR) {
            /* here is the input, which triggered this AJAX request */
            console.log(this.qty_input);
            /* here is any other parameter you set when initializing the ajax method */
            console.log(this.anything_else_i_want_to_pass_in);
        }
    });
});
</script>

En av grunnene til dette er bedre enn å sette den var, er at var er global og som sådan, overwritable ... hvis du har 2 ting som kan utløse ajax anrop, kan du i teorien utløse dem raskere enn ajax samtalen reagerer, og du vil ha verdi for den andre samtalen gikk inn i den første. Ved hjelp av denne metoden, ovenfor, som ikke ville skje (og det er ganske enkelt å bruke også).

Svarte 08/03/2012 kl. 20:36
kilden bruker

stemmer
3

La oss gå enkelt! :)

$.ajax({
    url: myUrl,
    context: $this, // $this == Current $element
    success: function(data) {
        $.proxy(publicMethods.update, this)(data); // this == Current $element
    }
});
Svarte 09/04/2013 kl. 11:31
kilden bruker

stemmer
2

En mer generell løsning for å sende asynkrone forespørsler via .ajax()jQuery API og lukkeanordninger til å passere flere parametere i funksjonen for tilbakeringing:

function sendRequest(method, url, content, callback) {
    // additional data for the callback
    var request = {
        method: method,
        url: url
    };

    $.ajax({
        type: method,
        url: url,
        data: content
     }).done(function(data, status, xhr) {
        if (callback) callback(xhr.status, data, request);
     }).fail(function(xhr, status) {
        if (callback) callback(xhr.status, xhr.response, request);
     });
};
Svarte 02/09/2013 kl. 10:26
kilden bruker

stemmer
1

For meg og andre newbies som nettopp har kontaktet med Javascript,
tror jeg at Closeure Solutioner litt slags for forvirrende.

Mens jeg fant det, kan du easilly passere så mange parametere som du vil hver ajax tilbakeringing ved hjelp av jQuery.

Her er to enklere løsninger .

Første, som @zeroasterisk er nevnt ovenfor, f.eks:

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 );
            ...
        } 
    });
});

Andre, passere selvdefinerte-datasett ved å legge dem inn i det XHR object som eksisterer i det hele Ajax-forespørsel-respons levetid.

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 );
            ...
        } 
    });
});

Som du kan se disse to løsningene har en ulempe at: du må skrive litt mer kode hver gang enn bare skrive:

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

Les mer om $ .ajax: http://api.jquery.com/jquery.ajax/

Svarte 22/05/2014 kl. 04:14
kilden bruker

stemmer
1
$(document).on('click','[action=register]',function(){
    registerSocket(registerJSON(),registerDone,second($(this)));
});

function registerSocket(dataFn,doneFn,second){
                 $.ajax({
                       type:'POST',
                       url: "http://localhost:8080/store/public/register",
                       contentType: "application/json; charset=utf-8",
                       dataType: "json",
                       data:dataFn
                 }).done ([doneFn,second])
                   .fail(function(err){
                            console.log("AJAX failed: " + JSON.stringify(err, null, 2));
                        });
}

function registerDone(data){
    console.log(JSON.stringify(data));
}
function second(element){
    console.log(element);
}

Sekundær måte:

function socketWithParam(url,dataFn,doneFn,param){
  $.ajax({
    type:'POST',
    url:url,
    contentType: "application/json; charset=utf-8",
    headers: { 'Authorization': 'Bearer '+localStorage.getItem('jwt')},
    data:dataFn
    }).done(function(data){
      doneFn(data,param);
    })
    .fail(function(err,status,xhr){
    console.log("AJAX failed: " + JSON.stringify(err, null, 2));
    });
}

$(document).on('click','[order-btn]',function(){
  socketWithParam(url,fakeDataFn(),orderDetailDone,secondParam);
});

function orderDetailDone(data,param){
  -- to do something --
}
Svarte 29/04/2016 kl. 06:39
kilden bruker

stemmer
1

Hvis noen fortsatt kommer her, dette er min ta:

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

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

Hva skjer her, etter binding til tilbakeringingsfunksjonen, vil den være tilgjengelig i funksjonen som this.

Denne ideen kommer fra hvordan React bruker bindfunksjonalitet.

Svarte 15/10/2016 kl. 08:46
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more