如何使用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
- Duplicate Event Listeners: Every time you click a delete button, you're adding a new click event to the
.confirm_deletebutton. After a few clicks, that confirm button will run the delete logic multiple times with one tap—super buggy! - 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
varwithconst/letto 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
相关产品推荐
相关产品推荐

