javascript - requetes - tp jquery




jQuery transmet plus de paramètres dans le rappel (10)

Allons simple! :)

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

Y at-il un moyen de transmettre plus de données dans une fonction de rappel dans jQuery?

J'ai deux fonctions et je veux que le callback à $.post , par exemple, passe à la fois les données résultantes de l'appel AJAX, ainsi que quelques arguments personnalisés

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

}

Je veux être capable de transmettre mes propres paramètres à un rappel, ainsi que le résultat renvoyé par l'appel AJAX.


C'est en fait plus facile que tout le monde le fait sonner ... surtout si vous utilisez la syntaxe de base $.ajax({}) rapport à l'une des fonctions d'aide.

Transmettez simplement la paire key: value comme vous le feriez sur n'importe quel objet, lorsque vous configurez votre requête ajax ... (car $(this) n'a pas encore changé de contexte, c'est toujours le déclencheur de l'appel bind ci-dessus)

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

Une des raisons est que cela vaut mieux que de paramétrer le var, c'est que la var est globale et en tant que telle, écrasable ... si vous avez 2 choses qui peuvent déclencher des appels ajax, vous pouvez en théorie les déclencher plus vite que l'appel ajax répond, et vous auriez la valeur pour le deuxième appel passé dans le premier. En utilisant cette méthode, ci-dessus, cela ne se produirait pas (et c'est assez simple à utiliser aussi).


En tant qu'addendum à la réponse de b01 , le second argument de $.proxy est souvent utilisé pour conserver this référence. Les arguments supplémentaires passés à $.proxy sont partiellement appliqués à la fonction, en la remplissant à l' $.proxy avec des données. Notez que tout argument $.post au callback sera appliqué à la fin, donc doSomething devrait avoir ceux à la fin de sa liste d'arguments:

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

Cette approche permet également à plusieurs arguments d'être liés au rappel:

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

J'ai fait une erreur dans le dernier message. Ceci est un exemple de travail pour passer un argument supplémentaire dans la fonction de rappel:

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

Lorsque vous utilisez doSomething(data, myDiv) , vous appelez réellement la fonction et n'y faites pas référence.

Vous pouvez passer la fonction doStomething directement, mais vous devez vous assurer que la signature est correcte.

Si vous voulez conserver DoSomething tel qu'il est, vous pouvez envelopper son appel dans une fonction anonyme.

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

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

A l'intérieur du code de fonction anonyme, vous pouvez utiliser les variables définies dans la portée englobante. C'est ainsi que fonctionne le scoping Javascript.


Pour moi, et d'autres débutants qui vient de contacter avec Javascript,
Je pense que la Closeure Solution est un peu trop confuse.

Alors que j'ai trouvé cela, vous pouvez facilement passer autant de paramètres que vous le souhaitez à chaque rappel ajax en utilisant jquery.

Voici deux solutions plus faciles .

Le premier, que @zeroasterisk a mentionné plus haut, exemple:

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

Deuxièmement, passez les données auto-définies en les ajoutant dans l' XHR object qui existe dans toute la durée de vie de la requête ajax-request.

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

Comme vous pouvez le voir ces deux solutions ont un inconvénient: vous avez besoin d'écrire un peu plus de code à chaque fois que d'écrire:

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

En savoir plus sur $ .ajax: http://api.jquery.com/jquery.ajax/


Une solution plus générale pour envoyer des requêtes asynchrones en utilisant l' .ajax() jQuery et les fermetures pour passer des paramètres supplémentaires à la fonction de rappel:

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

Vous pouvez également essayer quelque chose comme:

function clicked() {

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

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

function doSomething(curData, curDiv) {

}

en fait, votre code ne fonctionne pas parce que quand vous écrivez:

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

vous placez un appel de fonction comme troisième paramètre plutôt qu'une référence de fonction .


$(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);
}

Voie secondaire:

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




arguments