JQueryのコールバック関数にさらにデータを渡す方法はありますか?
2つの関数があり、$.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呼び出しから返された結果だけでなく、コールバックに独自のパラメーターを渡すことができるようにしたいと思います。
解決策は、クロージャを介して変数をバインドすることです。
より基本的な例として、コールバック関数とコールバック関数の例を受信して呼び出すサンプル関数を次に示します。
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 Arrow Functions を使用します。
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(extraStuff)
は 呼び出された そして、その呼び出しの結果は 関数ポインタ。
extraStuff
は引数としてdoSomething
に渡されるため、doSomething
関数のスコープ内にあります。
extraStuff
が返されたdoSomething
の匿名の内部関数で参照される場合、それはクロージャによって外部関数のextraStuff
引数にバインドされます。これは、doSomething
が返された後でも当てはまります。
上記のテストは行っていませんが、ここ24時間で非常によく似たコードを記述しており、説明したとおりに機能します。
もちろん、個人の好み/コーディング標準に応じて、単一の「extraStuff」オブジェクトの代わりに複数の変数を渡すことができます。
doSomething(data, myDiv)
を使用する場合、実際に関数を呼び出して、その関数への参照を作成しません。
doStomething
関数を直接渡すこともできますが、正しい署名を持つようにする必要があります。
DoSomethingをそのままにしておきたい場合は、その呼び出しを匿名関数でラップできます。
function clicked() {
var myDiv = $("#my-div");
$.post("someurl.php",someData, function(data){
doSomething(data, myDiv)
},"json");
}
function doSomething(curData, curDiv) {
...
}
無名関数コード内では、囲みスコープで定義された変数を使用できます。これは、Javascriptスコープの動作方法です。
実際、誰もがそれを鳴らすよりも簡単です...特に$.ajax({})
基本構文とヘルパー関数の1つを使用する場合。
Ajaxリクエストをセットアップするときに、オブジェクトでのようにkey: value
ペアを渡すだけです... ($(this)
はまだコンテキストを変更していないため、上記のバインド呼び出しのトリガーです)
<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>
Varを設定するよりも優れている理由の1つは、varがグローバルであり、上書き可能であるということです... ajax呼び出しをトリガーできるものが2つある場合、理論的には、ajax呼び出しが応答するよりも速くトリガーできるということです。 2番目の呼び出しの値が最初の呼び出しに渡されます。上記のこの方法を使用しても、それは起こりません(使用方法も非常に簡単です)。
今日の世界には、よりクリーンな別の答えがあり、別のスタックオーバーフローの答えから取ったものです。
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.
...
}
元の質問と回答は次のとおりです。 jQuery HOW TO ?? $ .ajax呼び出しの成功コールバックに追加のパラメーターを渡しますか?
次のようなものを試すこともできます。
function clicked() {
var myDiv = $("#my-div");
$.post("someurl.php",someData,function(data){
doSomething(data, myDiv);
},"json");
}
function doSomething(curData, curDiv) {
}
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");
簡単に行こう! :)
$.ajax({
url: myUrl,
context: $this, // $this == Current $element
success: function(data) {
$.proxy(publicMethods.update, this)(data); // this == Current $element
}
});
前回の投稿で間違いを犯しました。これは、コールバック関数で追加の引数を渡す方法の動作例です:
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;
}
.ajax()
jQuery APIとクロージャーを使用して追加のパラメーターをコールバック関数に渡すことにより、非同期リクエストを送信するためのより一般的なソリューション:
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);
});
};
誰かがまだここに来る場合、これは私の意見です:
$('.selector').click(myCallbackFunction.bind({var1: 'hello', var2: 'world'}));
function myCallbackFunction(event) {
var passedArg1 = this.var1,
passedArg2 = this.var2
}
ここで何が起こるかは、コールバック関数にバインドした後、関数内でthis
として利用可能になります。
この考えは、Reactがbind
機能をどのように使用するかに由来します。
$(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);
}
二次方法:
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 --
}
私とJavascriptを使用したばかりのその他の初心者のために、Closeure Solution
はちょっとわかりにくいと思います。
私はそれを見つけましたが、jqueryを使用してすべてのajaxコールバックに必要な数のパラメータを簡単に渡すことができます。
ここに2つの簡単な解決策があります。
1つ目は、@ 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 );
...
}
});
});
2つ目は、自己定義データをajax-request-responseの寿命全体に存在するXHR object
に追加して渡すことです。
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 );
...
}
});
});
ご覧のとおり、これらの2つのソリューションには次のような欠点があります。書くだけでなく、毎回少し多くのコードを書く必要があります。
$.get/post (url, data, successHandler);
$ .ajaxの詳細: http://api.jquery.com/jquery.ajax/
b01's answer の補遺として、$.proxy
の2番目の引数は、this
参照を保持するためによく使用されます。 $.proxy
に渡される追加の引数は、部分的に関数に適用され、データで事前に入力されます。 $.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;
}
実際には、コードは機能していません。
$.post("someurl.php",someData,doSomething(data, myDiv),"json");
関数参照ではなく、3番目のパラメーターとして関数呼び出しを配置します。