jQuery কলব্যাক আরও পরামিতি পাস


255

JQuery এর কলব্যাক ফাংশনে আরও ডেটা পাস করার কোনও উপায় আছে কি?

আমার দুটি ফাংশন রয়েছে এবং আমি কলব্যাকটি চাই $.post, উদাহরণস্বরূপ, এজেএক্স কলের ফলস্বরূপ ডেটা, পাশাপাশি কয়েকটি কাস্টম আর্গুমেন্টের মধ্যে

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

}

আমি আমার নিজস্ব পরামিতিগুলিতে একটি কলব্যাক দিতে সক্ষম হতে চাই, পাশাপাশি ফলাফলটি এজেএক্স কল থেকে ফিরে এসেছে।


14
এটা তোলে এর মূল্য উল্লেখ করে jQuery.ajax () 1.4 Ver থেকে কনটেক্সট সেটিং করেছে ( jquery14.com/day-01/jquery-14 ) এখানে তার ব্যবহার একটি উদাহরণ দেখুন: stackoverflow.com/questions/5097191/ajax-context- বিকল্প /…
রুসউ

এজ্যাক্স সমাপ্ত হওয়ার পরে ডেটা ফেরত দেওয়ার ক্ষেত্রে আমি আমার সমস্যাটি ছুঁড়েছি এবং তারপরে আমি কিছু করছি।
ওনাগগ্যাক

উত্তর:


340

সমাধানটি হ'ল বন্ধের মাধ্যমে ভেরিয়েবলের বাঁধাই।


আরও মৌলিক উদাহরণ হিসাবে, এখানে একটি উদাহরণ ফাংশন যা কলব্যাক ফাংশনটি গ্রহণ করে এবং কল করে, পাশাপাশি একটি উদাহরণ কলব্যাক ফাংশন:

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"

আপনার নির্দিষ্ট উদাহরণ হিসাবে, আমি .postjQuery এ ফাংশনটি ব্যবহার করি নি , তবে ডকুমেন্টেশনের একটি দ্রুত স্ক্যান থেকে বোঝা যায় যে কলটি পিছনে নিম্নলিখিত স্বাক্ষর সহ ফাংশন পয়েন্টার হওয়া উচিত :

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 ঘন্টা খুব অনুরূপ কোড লিখেছি এবং আমি বর্ণিত হিসাবে এটি কাজ করে।

আপনি অবশ্যই আপনার ব্যক্তিগত পছন্দ / কোডিং মানের উপর নির্ভর করে একক 'এক্সট্রা স্টাফ' অবজেক্টের পরিবর্তে একাধিক ভেরিয়েবলগুলি পাস করতে পারেন।


'Var doSomething =' এর উদ্দেশ্য কী? এটি কীভাবে কেবল ডোনসামিংকে একটি ফাংশন হিসাবে ঘোষণা করা থেকে আলাদা (যেমন ফাংশন ডসোমথিং (...)}})
ডেভ নীলি

7
এটা সত্যি না. এই দুটি কার্য ঘোষণার ক্ষেত্রে বিভিন্ন স্কোপ বিধি প্রযোজ্য। জেএস রানটাইম (ব্রাউজার পড়ুন) এর উপর নির্ভর করে আচরণটি অনেক আলাদা হয়। ফায়ারবগে স্ট্যাকট্রেস / ব্রেকপয়েন্টে প্রদর্শিত ফাংশনটির সাথে তুলনা করার চেষ্টাও করুন।
ইহোর কাহারলিচেনকো

1
ইহোর: দুটি ঘোষণার শৈলীর মধ্যে পার্থক্য সম্পর্কে আপনি একদম সঠিক। একটি ভাল ব্যাখ্যা এখানে: stackoverflow.com/questions/336859/...
bradhouse

2
উদাহরণের সুনির্দিষ্টতার কারণে ব্যবহারকারীরা এটি আরও সাধারণ সমস্যায় প্রয়োগ করার চেষ্টা করছেন তাদের অনুসরণ করা কিছুটা কঠিন হতে পারে। আমি একটি সরলীকৃত উদাহরণ যুক্ত করেছি যাতে এটি অনুসরণ করা কিছুটা সহজ হয়, পাশাপাশি নতুন পোস্ট প্রস্তাবিত সদৃশ সদৃশ হিসাবে এই প্রশ্নটি বন্ধ করে দেওয়া রোধ করার জন্য একটি তীর ফাংশন উদাহরণ। আপনি যদি আমার সম্পাদনাগুলি আপনার উত্তরের মূল অভিপ্রায় থেকে খুব দূরে বিচ্যুত হয়ে থাকেন বা অন্য কোনও উপায়ে অনুপযুক্ত অনুভব করেন তবে দয়া করে এটিকে আবার ঘোরান।

4
এই উত্তরের 4 টি পুনর্বিবেচনা
মেটাতে

82

ব্যবহার করার সময় doSomething(data, myDiv), আপনি আসলে ফাংশনটি কল করেন এবং এটিতে কোনও রেফারেন্স তৈরি করবেন না।

আপনি হয় doStomethingসরাসরি ফাংশনটি পাস করতে পারেন তবে আপনাকে অবশ্যই নিশ্চিত করতে হবে যে এটির সঠিক স্বাক্ষর রয়েছে।

আপনি যদি ডসমিংথিংটি এভাবেই চালিয়ে যেতে চান তবে আপনি তার কলটি কোনও বেনামি কার্যক্রমে মোড়ানো করতে পারেন।

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

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

বেনামে ফাংশন কোডের অভ্যন্তরে, আপনি এনকোলেসিং স্কোপে সংজ্ঞায়িত ভেরিয়েবলগুলি ব্যবহার করতে পারেন। জাভাস্ক্রিপ্ট স্কোপিং এইভাবে কাজ করে।


9
স্বচ্ছতার স্বার্থে এটিই সেরা সমাধান আইএমও। return function(...){...}ফাংশনের মধ্যে কোনও অতিরিক্ত ফাংশন নেই doSomething। আমি এখানে একই ধারণার আরেকটি সুস্পষ্ট উদাহরণ খুঁজে পেয়েছি: theelitist.net/…
উইলিয়াম ডেনিস

4
আমি মনে করি এটির সাথে একটি সমস্যা আছে। যদি আপনার অতিরিক্ত ডেটা (এই ক্ষেত্রে মাইডিভ) কলব্যাকের আগুনের আগে পরিবর্তিত হয় তবে আপনি নতুন মান পাবেন এবং পুরানোটি নয়! আমার ক্ষেত্রে, আমি একটি অ্যারে আইটেমগুলিতে অজ্যাক্স কলগুলি বন্ধ করে দিচ্ছিলাম এবং প্রথম সাফল্য () কলটি কার্যকর হওয়ার সময়, এটি মনে হয়েছিল যে এটি প্রথম আইটেমটিতে সফল হয়েছিল! ব্র্যাডহাউস এর উত্তর আমার জন্য কাজ করে।
ক্রিস

@ ক্রিস হ্যাঁ, বন্দী ভেরিয়েবলগুলি জাভাস্ক্রিপ্টে পরিবর্তন করা যেতে পারে। আপনি যদি এই আচরণটি না চান তবে মানটি ক্যাপচার করার জন্য আপনাকে একটি স্পষ্ট ফাংশন তৈরি করতে হবে। (function(myDiv){ ... })(myDiv)ভেরিয়েবল ক্যাপচারের জন্য সবচেয়ে সাধারণ আইডিয়ম একটি স্ব নির্বাহিত ফাংশন myDiv। এটি স্পষ্টভাবে @ ব্র্যাডহাউস উত্তরে সম্পন্ন করা হয়েছে।
ভিনসেন্ট রবার্ট

আপনি যদি এজ্যাক্সটিকে এন বার কল করেন তবে এই পদ্ধতিটি এন বিভিন্ন ফাংশন তৈরি করে এবং তাদের সাফল্য কলব্যাকে দেয় passes পারফোনমেন্সের ক্ষেত্রে এটি খারাপ। এই @zeroasterisk এর উত্তর পরিহার করা ভাল।
yılmaz


52

এটি সবার কাছে শব্দ করার চেয়ে এটি আরও সহজ ... বিশেষত যদি আপনি $.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>

ভেরটি সেট করার চেয়ে এটির আরও ভাল কারণগুলির মধ্যে একটি হ'ল ভেরটি বিশ্বব্যাপী এবং যেমন, ওভাররাইটেবল ... আপনার কাছে যদি এমন 2 টি জিনিস থাকে যা এজ্যাক্স কলগুলি ট্রিগার করতে পারে তবে আপনি থিয়ো এজ্যাক্স কল সাড়া দেওয়ার চেয়ে তাদের দ্রুত ট্রিগার করতে পারেন, এবং দ্বিতীয় কলটি প্রথমটিতে পাস করার জন্য আপনার মান হবে। উপরে এই পদ্ধতিটি ব্যবহার করে, এটি ঘটবে না (এবং এটি ব্যবহার করাও বেশ সহজ)।


3
এই ঠিক আমি খুঁজছিলাম ছিল। আমি কখন জানতাম না যে আপনি ডেটা টাইপটি জসন হিসাবে নির্দিষ্ট করেছেন এটি স্বয়ংক্রিয়ভাবে আপনার জন্য প্রতিক্রিয়াটিকে বিশ্লেষণ করেছে। এটি দুর্দান্ত (:
মুরগি

1
আমার কাছে কলব্যাক করার জন্য অতিরিক্ত প্যারামগুলি পাস করার সর্বোত্তম উপায় বলে মনে হচ্ছে। আমি আগ্রহী যদি এই পদ্ধতির সাথে কোনও ত্রুটি দেখেন? সবচেয়ে সহজ এবং সবচেয়ে মার্জিত। ধন্যবাদ!
জান জাইকা

" বৈচিত্রটি বৈশ্বিক এবং যেমন, ওভাররাইটেবল "। আপনি যদি এটি কোনও ফাংশনটির মধ্যে ঘোষণা করেন তবে তা নয়, যা উপরের সমাধানের চেয়ে অনেক বেশি পাঠযোগ্য। ক্লোজারগুলি ব্যবহার করা একটি পরিষ্কার পদ্ধতির - আমার উত্তরটি এখানে দেখুন: stackoverflow.com/a/18570951/885464
লরেঞ্জো পলিডোরি

5
@ লরেঞ্জো পোলিডোরি আমি একমত নই, আমি অতিরিক্ত পরামিতি পদ্ধতির চেয়ে আরও বেশি পাঠযোগ্য find
অ্যান্ড্রু প্লামার

2
এটি একেবারে উজ্জ্বল। কীভাবে এলাম আমি এর আগে কখনও দেখিনি। আমার দরকার নেই closureআমাকে কাজ করার দরকার এটি এবং এটি একেবারে টেক্কা, পরিষ্কার, সরল এবং অবিশ্বাস্য।
পাইওটর কুলা

21

আজকের বিশ্বে আর একটি উত্তর রয়েছে যা পরিষ্কার, এবং অন্য স্ট্যাক ওভারফ্লো উত্তর থেকে নেওয়া:

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 কিভাবে ?? aj .জ্যাক্স কলের জন্য সাফল্যের কলব্যাকে অতিরিক্ত পরামিতিগুলি পাস করুন?


8

আপনি নিম্নলিখিত মত কিছু চেষ্টা করতে পারেন:

function clicked() {

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

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

function doSomething(curData, curDiv) {

}

5

আপনি জাভাস্ক্রিপ্টের একটি বন্ধ ব্যবহার করতে পারেন:

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

3

আমি আমার পোস্টে একটি ভুল করেছি। কলব্যাক ফাংশনে অতিরিক্ত যুক্তি কীভাবে পাস করতে হয় এটি উদাহরণ হিসাবে কাজ করছে:

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

1
হয় আপনার নিজের মূল উত্তরটি সম্পাদনা করা উচিত, অথবা একটি নতুন উত্তর যুক্ত করার আগে এটি মুছে ফেলা উচিত।
ব্লেজমোনজার

3

আসুন সরল! :)

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

2

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

1

আমার এবং অন্যান্য নবাগতদের জন্য যারা জাভাস্ক্রিপ্টের সাথে সবেমাত্র যোগাযোগ করেছেন,
আমি মনে করি এটি Closeure Solutionকিছুটা বিভ্রান্তিকর।

যখন আমি এটি পেয়েছি, আপনি jquery ব্যবহার করে প্রতিটি এজ্যাক্স কলব্যাকের জন্য যতটা পরামিতিগুলি ইজিলি পাস করতে পারেন।

এখানে দুটি সহজ সমাধান রয়েছে

প্রথমটি, যা @ জেরোস্টারিস্ক উপরে উল্লেখ করেছে, উদাহরণস্বরূপ:

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

আপনি দেখতে পাচ্ছেন যে এই দুটি সমাধানের একটি অপূর্ণতা রয়েছে: প্রতিবার শুধু লেখার চেয়ে আপনাকে আরও কিছু কোড লিখতে হবে:

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

Aj .ajax: http://api.jquery.com/jquery.ajax/ সম্পর্কে আরও পড়ুন


1

এখনও যদি কেউ এখানে আসে তবে এটি আমার গ্রহণ:

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

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

এখানে কী ঘটে, কলব্যাক ফাংশনের সাথে আবদ্ধ হওয়ার পরে, এটি ফাংশনটির মধ্যেই উপলব্ধ হবে this

প্রতিক্রিয়া কীভাবে bindকার্যকারিতাটি ব্যবহার করে তা এই ধারণা থেকে আসে ।


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

মাধ্যমিক উপায়:

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

0

আসলে, আপনার কোডটি কাজ করছে না কারণ আপনি যখন লিখবেন:

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

আপনি কোনও ফাংশন রেফারেন্সের চেয়ে তৃতীয় প্যারামিটার হিসাবে একটি ফাংশন কল স্থাপন করেন ।


0

B01 এর উত্তরের সংযোজন হিসাবে , দ্বিতীয় যুক্তিটি $.proxyপ্রায়শই 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;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.