You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Bootstrap Modal实现删除确认并优化嵌套函数写法

Hey there! Let's break down the problem with your current code first, then fix it with clean, non-nested solutions.

The Core Issues in Your Current Code

  1. Duplicate Event Listeners: Every time you click a delete button, you're adding a new click event to the .confirm_delete button. After a few clicks, that confirm button will run the delete logic multiple times with one tap—super buggy!
  2. Unnecessary Nested Functions: The nested click handler inside deleteCustomer() makes your code harder to read, creates avoidable closure complexities, and can lead to memory leaks over time.

Solution 1: Separate Event Listeners + Bootstrap Modal Data Storage

We'll bind the confirm delete event once (on page load) instead of every time a delete button is clicked. We'll store the target row in the modal's data attributes to pass it between the delete trigger and confirm action.

Here's the revised code:

const myJSON = { 
  "customers": [
    { "id": 100, "first": "Mike", "last": "Johnson", "email": "mjohnson@gmail.com", "position": "Consultant" },
    { "id": 101, "first": "John", "last": "Dunn", "email": "jdunn@gmail.com", "position": "Programmer" },
    { "id": 109, "first": "Lisa", "last": "Morgan", "email": "lmorgan@gmail.com", "position": "Secretary" },
    { "id": 233, "first": "Kris", "last": "Bradley", "email": "kbradley@gmail.com", "position": "Programmer" },
    { "id": 57, "first": "Dave", "last": "Hart", "email": "dhart@gmail.com", "position": "Supervisor" }
  ] 
};

$(document).ready(function() {
  generateTbl();
  
  // Bind confirm delete handler ONCE, not every time a delete button is clicked
  $('.confirm_delete').on('click', function() {
    const targetTr = $('#deleteModal').data('targetTr');
    
    if (targetTr) {
      const table = $('#customers').DataTable();
      table.row(targetTr).remove().draw();
      // Clear stored data after deletion
      $('#deleteModal').removeData('targetTr');
    }
    
    $('#deleteModal').modal('hide');
  });
});

function generateTbl() {
  const jsonData = myJSON.customers;
  let buildTbl = `<div class='table-responsive'><table class='table table-striped' id='customers'><thead><tr><th>Customer ID</th><th>First Name</th><th>Last Name</th><th>Email</th><th>Position</th><th>Delete</th></thead><tbody>`;
  
  for (const key in jsonData) {
    // Use ES6 template strings for cleaner markup (no messy string concatenation!)
    buildTbl += `
    <tr id='row_${jsonData[key].id}'>
      <td data-id='id'>${$.trim(jsonData[key].id)}</td>
      <td data-id='first'>${$.trim(jsonData[key].first)}</td>
      <td data-id='last'>${$.trim(jsonData[key].last)}</td>
      <td data-id='email'>${$.trim(jsonData[key].email)}</td>
      <td data-id='position'>${$.trim(jsonData[key].position)}</td>
      <td class='text-center'>
        <button type='button' class='btn btn-default btn-sm customer_delete'>
          <span class='glyphicon glyphicon-remove'></span>
        </button>
      </td>
    </tr>`;
  }
  
  buildTbl += `</tbody></table></div>`;
  $('#customers_data').empty().append(buildTbl);
  buildDataTable('customers', [5], 5);
}

function buildDataTable(tblID, columnsArray, displayLength) {
  $('#' + tblID).DataTable({
    dom: 'Bfrtip',
    buttons: ['copy', 'csv', 'excel', 'pdf', 'print'],
    "iDisplayLength": displayLength,
    "aoColumnDefs": [{ 'bSortable': false, 'aTargets': columnsArray }]
  });
}

$('#customers_data').on('click', ':button.customer_delete', deleteCustomer);

function deleteCustomer() {
  const targetTr = $(this).parents('tr');
  // Store the target row in the modal's data attributes
  $('#deleteModal').data('targetTr', targetTr);
  // Show the modal
  $('#deleteModal').modal('show');
}

Solution 2: Custom Events (More Flexible)

If you prefer a decoupled approach, use custom events to trigger the delete action. This keeps your code even more modular:

// Inside document ready
$(document).ready(function() {
  generateTbl();
  
  // Confirm button triggers a custom "confirm-delete" event
  $('.confirm_delete').on('click', function() {
    $('#deleteModal').trigger('confirm-delete');
    $('#deleteModal').modal('hide');
  });
  
  // Listen for the custom event to run delete logic
  $('#deleteModal').on('confirm-delete', function() {
    const targetTr = $(this).data('targetTr');
    if (targetTr) {
      const table = $('#customers').DataTable();
      table.row(targetTr).remove().draw();
      $(this).removeData('targetTr');
    }
  });
});

// deleteCustomer function stays the same as Solution 1

Bonus Optimizations

  • Replaced var with const/let to avoid variable hoisting issues.
  • Used ES6 template strings for table markup—way easier to read and maintain than string concatenation.
  • Removed nested functions entirely, making the code flow more logical.

内容的提问来源于stack exchange,提问作者espresso_coffee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:50:43