Laravel 8中Datatable删除按钮执行load()后失效求助
问题解决方案
核心问题分析
首次删除正常是因为初始DOM元素绑定了事件,而load()刷新表格后,新生成的删除表单没有绑定事件,导致点击时触发表单默认提交行为,跳转到路由页面显示JSON。同时要优化表格更新方式,避免重复渲染带来的问题,再扩展批量删除功能。
一、修复单次删除异常
1. 统一表单类名
Blade代码里的删除表单类需和JS绑定的类名统一,修改为delete-fm:
<td class="action-btn"> <form method="POST" class="delete-fm"> @csrf @method('DELETE') <input type="hidden" name="id" value="{{$user->id}}"> <button type="submit" class="btn btn-sm bg-danger-light btn-rounded"> <i class="zmdi zmdi-delete"></i> </button> </form> </td>
2. 改用事件委托绑定事件
将事件绑定到静态父元素(比如表格#user-table),确保动态生成的表单也能触发事件:
// 事件委托绑定删除表单提交事件 $('#user-table').on('submit', '.delete-fm', function(e) { e.preventDefault(); // 缓存当前表单对象,方便后续操作 const $form = $(this); $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }); const formData = new FormData(this); $.ajax({ url: "{{route('users.destroy')}}", type: 'POST', data: formData, dataType: 'JSON', contentType: false, cache: false, processData: false, encode: true, }).done(function(data) { if(data.success == false) { Snackbar.show({ text: data.message, pos: 'top-right', actionTextColor: '#fff', backgroundColor: '#e2a03f' }); }else{ Snackbar.show({ text: data.message, pos: 'top-right', actionTextColor: '#fff', backgroundColor: '#8dbf42' }); // 直接移除当前行,替代load()刷新 $form.closest('tr').remove(); } }).fail(function() { Snackbar.show({ text: '删除失败,请重试', pos: 'top-right', actionTextColor: '#fff', backgroundColor: '#ff4757' }); }); });
二、实现无刷新批量删除
1. 修改Blade表格模板,添加复选框和批量按钮
<!-- 表格头部添加全选复选框 --> <thead> <tr> <th><input type="checkbox" id="select-all"></th> <th>头像</th> <th>姓名</th> <th>邮箱</th> <th>编辑</th> <th>删除</th> </tr> </thead> <tbody> @foreach ($users as $user) <tr> <td><input type="checkbox" class="user-checkbox" value="{{$user->id}}"></td> <td> <h2 class="table-avatar"> @if(!empty($user->avatar)) <span class="avatar avatar-sm mr-2"> <img class="avatar-img rounded-circle" src="{{asset('storage/users/'.$user->avatar)}}" alt="用户头像"> </span> @else <p class="table-img-name">{{substr($user->name,0,1)}}</p> @endif </h2> </td> <td>{{$user->name}}</td> <td>{{$user->email}}</td> <td class="action-btn"> <a data-id="{{$user->id}}" data-name="{{$user->name}}" data-email="{{$user->email}}" class="btn btn-sm bg-success-light btn-rounded editbtn" id="edit-user" href="javascript:void(0)"> <i class="zmdi zmdi-edit"></i> </a> </td> <td class="action-btn"> <form method="POST" class="delete-fm"> @csrf @method('DELETE') <input type="hidden" name="id" value="{{$user->id}}"> <button type="submit" class="btn btn-sm bg-danger-light btn-rounded"> <i class="zmdi zmdi-delete"></i> </button> </form> </td> </tr> @endforeach </tbody> <!-- 表格外添加批量删除按钮 --> <div class="mt-3"> <button id="batch-delete-btn" class="btn btn-danger">批量删除选中用户</button> </div>
2. 添加批量删除的JS逻辑
// 全选/取消全选 $('#select-all').on('change', function() { $('.user-checkbox').prop('checked', $(this).prop('checked')); }); // 批量删除按钮点击事件 $('#batch-delete-btn').on('click', function() { // 获取选中的用户ID const selectedIds = $('.user-checkbox:checked').map(function() { return $(this).val(); }).get(); if(selectedIds.length === 0) { Snackbar.show({ text: '请选择要删除的用户', pos: 'top-right', actionTextColor: '#fff', backgroundColor: '#e2a03f' }); return; } if(confirm('确定要删除选中的用户吗?')) { $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }); $.ajax({ url: "{{route('users.batch-destroy')}}", type: 'POST', data: { ids: selectedIds }, dataType: 'JSON', }).done(function(data) { if(data.success) { Snackbar.show({ text: data.message, pos: 'top-right', actionTextColor: '#fff', backgroundColor: '#8dbf42' }); // 移除所有选中的行 $('.user-checkbox:checked').closest('tr').remove(); // 取消全选状态 $('#select-all').prop('checked', false); } else { Snackbar.show({ text: data.message, pos: 'top-right', actionTextColor: '#fff', backgroundColor: '#e2a03f' }); } }).fail(function() { Snackbar.show({ text: '批量删除失败,请重试', pos: 'top-right', actionTextColor: '#fff', backgroundColor: '#ff4757' }); }); } });
3. 控制器添加批量删除逻辑
// 在UserController中添加批量删除方法 public function batchDestroy(Request $request) { $request->validate([ 'ids' => 'required|array', 'ids.*' => 'exists:users,id' ]); User::destroy($request->ids); return response()->json([ 'success' => true, 'message' => '选中用户已删除' ]); } // 路由文件中添加批量删除路由 Route::post('users/batch-destroy', [UserController::class, 'batchDestroy'])->name('users.batch-destroy'); // 同时确保单个删除路由正确 Route::delete('users/{user}', [UserController::class, 'destroy'])->name('users.destroy');
关键说明
- 事件委托:通过绑定到静态父元素,解决动态生成元素的事件绑定问题,彻底避免
load()带来的事件丢失问题; - 行级删除:直接移除对应DOM行,比
load()更高效,也避免重新渲染页面; - 批量删除:通过收集选中ID,一次性提交删除,减少Ajax请求次数,提升体验。
内容的提问来源于stack exchange,提问作者zuma boy
相关产品推荐
相关产品推荐

