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 并返回结果,但是它调用它的次数太多了。

例如,如果我选中三个框,它将调用 cfc 方法 7 次,如果我选中两个框,它将调用 cfc 方法 5 次。我检查了 cfc 方法被调用 19 次的所有 7 个框。

我的第一个想法可能是 cfc 被调用了正确的次数,但是回调处理程序被调用了很多,因为每个实例都会在返回结果时调用它的响应处理程序,所以我创建了机构对象的全局实例并且只是每次都调用该方法,但是我得到了相同的结果。

有谁知道为什么会发生这种情况?

*(编辑)我只是在实际 cfc 中添加了一个计数以及调用计数,它实际上调用了 cfc 方法太多次。

4

1 回答 1

1

“因为回调处理程序不知道它应该处理哪个特定响应,所以它们都处理所有响应”

这就是回调处理程序的工作方式。他们应该处理所有的响应。问题是您正在创建多个回调处理程序,它们都做同样的事情;并且每个响应都被发送到每个处理程序。

通过saveResponses使用 JavaScript匿名函数function(){...}作为方法参数传递)在函数中设置处理程序,您将为该类附加额外的回调处理程序。如果您为每个请求创建和销毁对象,这可能是有道理的,但正如您在帖子评论中所讨论的那样,您最好创建一个实例。使用这种方法,您也应该在此函数之外设置回调处理程序。

为了说明发生了什么,让我们看看当您选中 3 个框并运行时会发生什么saveResponses

saveResponses(...){

  //...

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

  //...

}

处理程序的附加解释了 3 个复选框 -> 7 个调用。

  • 第一次调用它时,您有 1 个处理程序和 1 个结果。
  • 第二次调用它时,您添加了一个处理程序(2 个处理程序),因此您的 1 结果被处理了两次。
  • 第三次调用它时,添加了第三个处理程序,因此 1 个结果处理了 3 次。

saveResponse因为方法被多次调用.each();它快速循环遍历 jQuery 选择器返回的每个项目,为每个项目运行一次 each-handler 函数。

加起来最多只有 6 个调用,所以仍然有问题,但是您可以看到这将如何迅速成为一个大问题。第 7 个可能是因为 ajax 请求的异步性质。真正发生的事情可能更像是:

  • saveResponses
    1. 添加回调处理程序
    2. 发送ajax请求
  • saveResponses
    1. 添加回调处理程序
    2. 发送ajax请求
  • 第一个请求的结果回来了。有 2 个处理程序,所以它被发送到两个处理程序。
  • 到目前为止看到了 2 个回调
  • 第二个请求的结果回来了。2 个处理程序,发送给两者。
  • 到目前为止看到 4 个回调
  • saveResponses
    1. 添加回调处理程序
    2. 发送ajax请求
  • 第三个请求的结果回来了。3 个处理程序,发送给所有 3 个处理程序。
  • 到目前为止看到了 7 个回调

课程:在调用者之外声明/分配处理程序(靠近类实例化的地方最有意义)。

如果您真的想学习 JavaScript——而且你应该——选择一份JavaScript: The Good Parts。它很短,但写得非常好,使复杂的概念更容易理解。其中一些在你目前的技能水平上可能没有多大意义,但首先关注触手可及的东西(例如匿名函数),然后在你真正了解这些之后,转向更难的东西,比如模块。

于 2012-12-26T14:35:54.090 回答