3

私は cfajaxproxy を初めて使用します。いくつかのチェック ボックスを選択してから、チェックされたすべてのチェックボックスをループし、結果を cfajaxproxy と jQuery を使用してデータベースに保存しようとしています。

マークアップはクエリをループすることによって生成されますが、問題が発生している領域のサンプルを次に示します。

<span id="1569_2627_text">I certify that the employee has been trained in the use of the following 
equipment (please check all that apply):</span><br />

<input type="hidden" name="2627_max_length" id="2627_max_length" value="">
<input type="hidden" name="2627_min_value" id="2627_min_value" value="">
<input type="hidden" name="2627_max_value" id="2627_max_value" value="">
<input type="hidden" name="2627_regex_format" id="2627_regex_format" value="">
<input type="hidden" name="2627_system_type" id="2627_system_type" value="">
<input type="hidden" name="2627_app_type_version" id="2627_app_type_version" value="1569">
<input type="hidden" name="2627_question_type" id="2627_question_type" value="CM">


<label>
    <input class="questionChoice" type="checkbox" name="2627" 
    value="8509" data-app_type_version="1569">
        <span>Face Shield<span>
</label><br />

<label>
    <input class="questionChoice" type="checkbox" name="2627" 
    value="8510" data-app_type_version="1569">
        <span>Neoprene Gloves<span>
</label><br />

<label>
    <input class="questionChoice" type="checkbox" name="2627"
    value="8511" data-app_type_version="1569">
        <span>Apron<span>
</label><br />

<label>
    <input class="questionChoice" type="checkbox" name="2627"
    value="8512" data-app_type_version="1569">
        <span>Boots<span>
</label><br />

<label>
    <input class="questionChoice" type="checkbox" name="2627"
    value="8513" data-app_type_version="1569">
        <span>Wizard Glove<span>
</label><br />

<label>
    <input class="questionChoice" type="checkbox" name="2627"
    value="8514" data-app_type_version="1569">
        <span>Insulated Mitt<span>
</label><br />

<label>
    <input class="questionChoice" type="checkbox" name="2627"
    value="8515" data-app_type_version="1569">
        <span>Insulated Glove<span>
</label><br />

<button class="add_answer" value="2627" data-app_type_version="1569" disabled>Add answer</button>

これが私のcfajaxプロキシタグです:

<cfajaxproxy cfc="#APPLICATION.cfMapping#.Agency.Agency" 
jsclassname="agency_object">

チェックボックスごとに実行する関数は次のとおりです。

function saveResponses(question_no, answerValue){

  var myagOBJ = new agency_object();
  myagOBJ.setHTTPMethod('POST');
  myagOBJ.setCallbackHandler(function(result) {
    numOfCalls++;
    alert(result+ ", call number: "+ numOfCalls);   
  });   
  myagOBJ.setErrorHandler(null);

  myagOBJ.store_prepopulated_response(
     agency_id = #SESSION.agency_object.get_id()#,
     jQuery("select##site").val(),
     question_no,
     answerValue
  );
}

各チェックボックスをループする jQuery コードは次のとおりです。

$("div##" + div + " [name=" + question_no + "]:checked").each(function() {
    answerText = $(this).next().text();
    answerValue = $(this).val();
    identifier = question_no + "_" + answerValue;
    if(answers["q_" + identifier] ===  undefined) {
    formAppend();
    answers["q_" + identifier] = answerValue;
    alert("From Checkbox");
    saveResponses(question_no, answerValue);
    $("div##saved_answers table").append(
        "<tr id=\"" + identifier + "\"><td><strong>" + formName + 
        "</strong><br>" + questionText + "</td><td>" + answerText + 
        "<br><button data-app_type_version=\"" + div + 
        "\"class=\"remove\" value=\"" + identifier + 
        "\">Remove</button></td></tr>"
    );
    }
});

呼び出している cfc のメソッドは次のとおりです。

<cffunction name="store_prepopulated_response" access="remote" returntype="string" verifyclient="true">
<cfargument name="agency_id" type="numeric" required="true">
<cfargument name="site_id" type="numeric" required="true">
<cfargument name="question_no" type="numeric" required="true">
<cfargument name="response" type="string" required="true">



<cfreturn "Agency id: #agency_id#, Site ID: #site_id#, Question No: #question_no#, Resonse: #response#">
</cffunction>

私はまだそれが機能することを確認するために物事をテストしているだけなので、多くの関数はテスト結果を返す以外は実際に何かをしています.

このコードを実行すると、cfc が正常に呼び出され、結果が返されますが、何度も呼び出されています。

たとえば、3 つのボックスをオンにすると、cfc メソッドが 7 回呼び出され、2 つのボックスをオンにすると、cfc メソッドが 5 回呼び出されます。cfc メソッドが 19 回呼び出される 7 つのボックスすべてをチェックします。

私の最初の考えは、cfc が正しい回数呼び出されている可能性がありますが、結果が返されたときに各インスタンスが応答ハンドラーを呼び出すため、callbackhandler が多く呼び出されているため、agency_object のグローバル インスタンスを作成し、毎回メソッドを呼び出しますが、同じ結果が得られました。

なぜこれが起こるのか誰か知っていますか?

*(編集) 実際の cfc に呼び出し回数も追加しましたが、実際には cfc メソッドの呼び出し回数が多すぎます。

4

1 に答える 1

1

「コールバックハンドラーは、どの特定の応答を処理する必要があるかを認識していないため、それらすべてがすべての応答を処理します」

これがコールバック ハンドラの仕組みです。彼らはすべての応答を処理する必要があります。問題は、すべて同じことを行う複数のコールバック ハンドラを作成していることです。そして、各応答が各ハンドラーに送信されます。

saveResponsesJavaScript匿名関数(メソッド引数として渡す) を使用して関数内からハンドラーを設定することによりfunction(){...}、そのクラスに追加のコールバック ハンドラーを追加します。リクエストごとにオブジェクトを作成および破棄する場合、これは理にかなっているかもしれませんが、投稿のコメントで説明したように、インスタンスを 1 つ作成した方がよいでしょう。そのアプローチでは、コールバック ハンドラをこの関数の外にも設定する必要があります。

何が起こっているかを説明するために、3 つのボックスをチェックして実行するとどうなるかを見てみましょうsaveResponses

saveResponses(...){

  //...

  myagOBJ.setCallbackHandler(function(result) {
    numOfCalls++;
    alert(result+ ", call number: "+ numOfCalls);   
  });

  //...

}

ハンドラーを追加すると、3 つのチェックボックス -> 7 つの呼び出しが説明されます。

  • 初めて呼び出すと、1 つのハンドラーと 1 つの結果が得られます。
  • 2 回目に呼び出すと、ハンドラー (2 つのハンドラー) が追加されているため、1 つの結果が 2 回処理されます。
  • 3 回目に呼び出すと、3 番目のハンドラーが追加されるため、1 つの結果が 3 回処理されます。

saveResponse.each()メソッドのために複数回呼び出されます。jQueryセレクターによって返された各アイテムをすばやく連続してループし、各ハンドラー関数をそれぞれ1回実行します。

これは最大 6 回の呼び出しにすぎないため、まだ何かが正しくありませんが、これがすぐに大きな問題になることがわかります。7 番目は、ajax 要求の非同期性のためにおそらく発生します。実際に起こっていることは、おそらく次のようなものです。

  • saveResponsesと呼ばれる
    1. コールバック ハンドラを追加
    2. ajaxリクエストを送る
  • saveResponsesと呼ばれる
    1. コールバック ハンドラを追加
    2. ajaxリクエストを送る
  • 最初のリクエストの結果が返ってきます。2 つのハンドラーがあるため、両方に送信されます。
  • これまでに 2 件のコールバックが確認されました
  • 2 番目のリクエストの結果が返ってきます。両方に送信される 2 つのハンドラー。
  • これまでに確認された 4 つのコールバック
  • saveResponsesと呼ばれる
    1. コールバック ハンドラを追加
    2. ajaxリクエストを送る
  • 3 回目のリクエストの結果が返ってきます。3 つのハンドラー、3 つすべてに送信されます。
  • これまでに確認された 7 件のコールバック

教訓: ハンドラーを呼び出し元の外で宣言/割り当てます (クラスがインスタンス化される場所の近くが最も理にかなっています)。

JavaScript について本当に学びたいのであれば、JavaScript のコピーを手に入れてください: The Good Parts . 非常に短いですが、非常によく書かれており、複雑な概念を理解しやすくなっています。その中には、現在のスキル レベルではあまり意味をなさないものもありますが、最初は手の届くところにあるもの (匿名関数など) に集中し、それらを十分に理解したら、モジュールなどのより難しいものに進みます。

于 2012-12-26T14:35:54.090 に答える