jQuery $.post 在上次意外点击后影响 table 中的多行

jQuery $.post affecting multiple rows in table after a previous accidental click

我有一个网页允许授权用户更新或删除 MySQL table 中的行。 table 包含列 id (INT)、label (VARCHAR)、details (VARCHAR)、templateId (INT) 和 auditable(TINYINT,0 或 1)。这个table在前端显示为HTML,显示"Label"、"Details"、"Auditable?"和"Edit/Delete"列。

单击一行上的 "Edit" 按钮,更改生成的 Bootstrap 模态表单中的一些数据,然后单击 "Save Changes" 可以正常工作。当我单击 "Edit",单击表单上的 "Cancel",然后单击另一行(比如说,我不小心单击了错误的行)时,就会出现问题。当我单击按钮对新单击的行执行编辑时,该行和最初单击的行都会受到影响。 Chrome 控制台显示两个 JavaScript 对象正在通过 $.post() 发送,但我无法从我编写的逻辑中找出原因(见下文)。我查看了 MySQL 并且那里有重复的结果,确认页面准确反映了更新。 jQuery 中是否有一些我不知道的 $.get$.post 缓存行为? (删除功能也会出现这种情况,但为了简洁起见,我限制了这个问题)。

主页(GUI):

// The 'edit this row' button that brings up the modal form
$(".edit-action").click(function() {

  // Clear any previously set values in form
  $("#editActionLabel").val('');
  $("#editActionDetails").val('');
  $(".radio-edit-action").prop("checked", false);

  // All edit button id's in GUI table will be "edit-action-[`id` in database]" 
  // Grab number out of there and convert from string to number
  var actionId = $(this).attr("id");
  actionId = parseInt(actionId.slice(12));

  // Grab data from database to populate fields
  $.get("data.php?a=actionData&actionId=" + actionId, function(d) {

    // Returning a JSON encoded array isn't working, 
    // so I'm sending back a comma-separated string instead 
    var response = d.split(",");
    var label = response[0];
    var details = response[1];
    var auditable = parseInt(response[2]);

    $("#editActionLabel").val(label);
    $("#editActionDetails").val(details);

    if (auditable == 1) {
      $("#editAuditableNo").prop("checked", false);
      $("#editAuditableYes").prop("checked", true);
    } else if (auditable == 0) {
      $("#editAuditableYes").prop("checked", false);
      $("#editAuditableNo").prop("checked", true);
    }

    // Only reset `auditable` variable if selection was changed
    $(".radio-edit-action").change(function() {
      auditable = $(this).val();
      auditable = parseInt(auditable);
    });

    // User clicks "Save Changes" instead of "Cancel"
    $("#executeEdit").click(function() {

      var label = $("#editActionLabel").val();
      var details = $("#editActionDetails").val();

      var obj = {
        "operation": "edit",
        "actionId": actionId,
        "label": label,
        "details": details,
        "auditable": auditable
      };

      console.log("The object passed to 'edit' this row:");
      console.log(obj);

      $.post("data.php", obj, function(r) {
        // Confirm success or failure to user
        $("#crudResult").html(r);
      });
    }); // end click

  });

}); // end 'edit action'

data.php(通过 AJAX 调用以在数据库中执行更新。仅显示相关代码):

$debug = false;

$operation      =   $_POST['operation'];
$action_id      =   (isset($_POST['actionId'])      ?   $_POST['actionId']    : '');         
$label          =   (isset($_POST['label'])         ?   $_POST['label']       : 'NULL');
$details        =   (isset($_POST['details'])       ?   $_POST['details']     : 'NULL');
$auditable      =   (isset($_POST['auditable'])     ?   $_POST['auditable']   : 'NULL');  

switch ($operation) {

    case 'edit':

        $query = "
            UPDATE actions 
            SET label='$label', 
                details='$details', 
                auditable=$auditable
            WHERE id=$action_id 
            LIMIT 1";

        // DB connection not shown. Yes, I know I should be using PDO...
        $result = mysqli_query($db_conn, $query);

        // PHP echoes out the result; let the calling JavaScript figure out where to place it
        if ($result) {
            echo '<p class="text-success">Action successfully updated!</p>';
        } else {
            echo '<p class="text-warning">There was an error and the action could not be edited.</p>';
            // Don't show error to user in production, when $debug should be false
            if ($debug) {
                echo '<p><b>Error:</b> ' . mysqli_error($db_conn) . '</p>';
            }
        }

        break;

    /* case 'delete': ... */

}

模态表单遵循 Bootstrap 的模板 HTML,只是字段的集合和几个按钮(没有 <form> 围绕它)。如果我能澄清任何问题,请告诉我。

对服务器的请求发生了多少次?我敢打赌是两次。 问题出在客户端。 对于您所做的每一次编辑点击,都会创建一个新的保存点击功能。 您不需要为每个编辑点击添加它,将其从编辑点击功能中取出。

希望对您有所帮助。