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

Laravel 8中通过Ajax实现无刷新页面重载div及数据表格

问题原因

你当前代码不生效的核心问题有5个:

  • load()方法使用错误:jQuery的load()第一个参数必须是服务端请求地址,你写$("#tbody").load("#tbody")本质是请求当前页面的#tbody锚点,不会发起服务端请求拉取最新数据
  • 事件绑定逻辑错误:你把表格刷新逻辑绑定在saveBtn的click事件里,还嵌套在表单submit回调内部,既会导致事件重复绑定,也会因为表单submit默认触发时机问题,刷新逻辑根本不会在数据提交成功后执行
  • DataTables插件冲突:你手动修改DOM的方式和DataTables的内部缓存机制不兼容,哪怕手动插入新行,插件也识别不到,分页、排序功能会异常
  • 回调逻辑缺失:ajax提交成功的回调里只做了重置表单、关闭弹窗操作,根本没有执行任何表格更新动作
  • 额外小bug:blade模板里操作按钮的data-id属性用了PHP字符串拼接写法' . $row->id . ',会直接把点号输出到页面上,后续编辑删除功能拿不到正确的书籍ID
正确实现方案

给你两种可落地的实现,优先选第二种,和DataTables适配性更好。

方案一:保留现有DOM渲染逻辑,局部重载tbody

1. 调整控制器

在BookController里新增一个专门返回表格tbody内容的接口,原有的index和insert方法保留:

// 新增方法,返回渲染好的tbody HTML
public function getBookTbody()
{
    $books = Book::all();
    return view('partials.book_tbody', compact('books'))->render();
}

2. 拆分视图

新建resources/views/partials/book_tbody.blade.php,把原来写在tbody里的循环内容挪过去,修正data-id的写法错误:

@foreach ($books as $row)
<tr>
    <th scope="row">{{ $row->id }}</th>
    <td>{{$row->title }}</td>
    <td>{{ $row->author }}</td>
    <td>
        <a href="javascript:void(0)" data-id="{{ $row->id }}" class="edit btn btn-primary btn-sm editBook">Edit</a>
        <a href="javascript:void(0)" data-id="{{ $row->id }}" class="btn btn-danger btn-sm deleteBook">Delete</a>
    </td>
</tr>
@endforeach

原来的books.blade.php里的tbody部分改成引入partial,首次加载直接渲染:

<tbody id="tbody">
    @include('partials.book_tbody')
</tbody>

3. 补全路由

在routes/web.php里注册新接口:

Route::get('/books/tbody', [BookController::class, 'getBookTbody'])->name('book.tbody');
// 保留原有book.index、book.add路由

4. 修正JS逻辑

删掉错误的事件绑定,把刷新逻辑移到ajax成功回调里,处理DataTables兼容问题:

// 存下DataTable实例,方便后续销毁重建
const bookTable = $("#datatables").DataTable({});

$("#bookForm").submit(function(e) {
    e.preventDefault();
    $.ajax({
        type: "POST",
        url: "{{route('book.add')}}",
        data: $(this).serialize(), // 直接序列化表单,不用手动拿每个字段
        success: function(response) {
            if (response) {
                $("#bookForm")[0].reset();
                $("#addmodel").modal("hide");
                // 拉取最新tbody内容替换
                $("#tbody").load("{{ route('book.tbody') }}", function() {
                    // 销毁旧实例重新初始化,解决DataTables缓存不更新问题
                    bookTable.destroy();
                    $("#datatables").DataTable({});
                });
            }
        },
        error: function(xhr) {
            console.log(xhr.responseText);
            alert('提交失败,请重试');
        }
    });
});

方案二:使用DataTables原生ajax重载(推荐)

不用拆分视图、不用手动操作DOM,稳定性更高:

1. 调整控制器

新增返回书籍列表JSON的接口:

public function bookList()
{
    return response()->json(Book::all());
}

2. 补全路由

Route::get('/books/list', [BookController::class, 'bookList'])->name('book.list');

3. 调整视图和JS

把原来tbody里的@foreach循环全部删掉,tbody留空即可,DataTables会自动渲染行:

<tbody id="tbody"></tbody>

修改DataTables初始化配置,新增成功后直接调用插件自带的reload方法:

const bookTable = $("#datatables").DataTable({
    ajax: "{{ route('book.list') }}",
    columns: [
        {data: 'id', title: 'Book_ID'},
        {data: 'title', title: 'Book_Name'},
        {data: 'author', title: 'Auther'},
        {
            data: 'id',
            title: 'Action',
            render: function(id) {
                return `<a href="javascript:void(0)" data-id="${id}" class="edit btn btn-primary btn-sm editBook">Edit</a>
                        <a href="javascript:void(0)" data-id="${id}" class="btn btn-danger btn-sm deleteBook">Delete</a>`
            }
        }
    ]
});

$("#bookForm").submit(function(e) {
    e.preventDefault();
    $.ajax({
        type: "POST",
        url: "{{route('book.add')}}",
        data: $(this).serialize(),
        success: function(response) {
            if (response) {
                $("#bookForm")[0].reset();
                $("#addmodel").modal("hide");
                // 直接调用DataTables原生重载方法,自动拉取最新数据渲染
                bookTable.ajax.reload();
            }
        },
        error: function(xhr) {
            console.log(xhr.responseText);
            alert('提交失败,请重试');
        }
    });
});

两种方案都能实现无刷新局部更新表格,方案二后续做编辑、删除、搜索、分页的扩展更方便,不会出现DOM和插件状态不一致的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 23:36:36