如何用AJAX响应填充HTML表格?Laravel无刷新更新问题
问题:Laravel Blade页面无刷新更新表格内容失败
我有个Laravel Blade视图页面,想实现无需刷新页面就能更新内容。Blade.php能正常从MySQL取数据,但AJAX/JavaScript代码跑不起来。我有C#开发背景,从没接触过AJAX/JavaScript/PHP,现在遇到的问题是AJAX调用返回的内容看起来像JSON,但没法正确识别访问内部元素。控制器能正常返回数据,我要实现的是:每5秒从数据库获取新数据,更新现有表格(有新数据时更新)。
视图代码(view.blade.php)
<table class="table custom--table" id="mainTable"> <thead> <tr> <th>@lang('ID')</th> <th>@lang('Name')</th> <th>@lang('Date')</th> <th>@lang('Details')</th> </tr> </thead> <tbody> @forelse($items as $data) <tr> <td data-label="@lang('ID')"> {{ $loop->index + 1 }} </td> <td data-label="@lang('Name')">{{ $data->name }}</td> <td data-label="@lang('Date')">{{ $data->created_at }}</td> <td id="detailz" data-label="@lang('Details')">{{ $data->details }}</td> </tr> @empty <tr> <td colspan="100%" class="text-center justify-content-center">@lang('No data.')</td> </tr> @endforelse </tbody> </table>
失效的AJAX代码
function updatePost() { setInterval(function() { $.ajax({ type: "GET", url: "{{route('user.posts.update')}}", // 路由正常 success: function( response ){ $('#mainTable')[0].reset(); $("tbody").html(""); $.each(response, function( index, value ) { var row = $("<tr><td>" + value.name + "</td><td>" + value.details + "</td><td>" + value.created_at + "</td><td>"); $("tbody").append(row); }); }, error: function( response ){ console.log("Error!"); console.log(response); } }); }, 5000); // 每5秒执行一次 }
控制器代码(controller.php)
public function postUpdate(){ $pageTitle = 'Post Update'; $data = DataHistory::where('user_id', Auth::user()->id)->latest()->paginate(getPaginate()); return response()->json($data); }
返回的数据示例
{ "current_page":1, "data":[{ "id":34, "user_id":1, "name":"RANDOM NAME DATA", "details":"RANDOM DETAILS", "created_at":"2022-11-16T15:02:56.000000Z" },{ "id":32, "user_id":1, "name":"RANDOM NAME DATA 2", "details":"RANDOM DETAILS 2", "created_at":"2022-11-16T10:19:29.000000Z" }], "first_page_url":"https://xyz.com/posts/update/?page=1", "from":1, "last_page":1, "last_page_url":"https://xyz.com/posts/update/?page=1", "links":[{ "url":null, "label":"« Previous", "active":false },{ "url":"https://xyz.com/posts/update/?page=1", "label":"1", "active":true },{ "url":null, "label":"Next »", "active":false }], "next_page_url":null, "path":"https://xyz.com/posts/update/", "per_page":20, "prev_page_url":null, "to":7, "total":7 }
解决方案
你的方向是对的,问题出在几个细节上:
- 数据访问层级错误:控制器返回的是Laravel分页对象的JSON,实际业务数据在
response.data数组里,你现在直接遍历整个response,会把分页的元数据(比如current_page)也当成数据处理,自然取不到name等属性。 - 表格重置方法错误:
$('#mainTable')[0].reset()是表单的专属重置方法,表格没有这个方法,直接删除该行即可。 - HTML结构不完整:拼接的
<tr>标签最后缺少闭合的</tr>,会导致DOM结构异常。 - 重复ID问题:Blade循环里给
<td>加了id="detailz",多个行重复ID违反HTML规范,改成class或者直接去掉。
修正后的AJAX代码:
function updatePost() { setInterval(function() { $.ajax({ type: "GET", url: "{{route('user.posts.update')}}", dataType: "json", // 明确指定返回类型为JSON,避免解析歧义 success: function( response ){ $("tbody").html(""); // 遍历response中的业务数据数组 $.each(response.data, function( index, value ) { // 补全HTML结构,修正ID为class,保持序号逻辑和Blade一致 var row = $(`<tr> <td data-label="@lang('ID')">${index + 1}</td> <td data-label="@lang('Name')">${value.name}</td> <td data-label="@lang('Date')">${value.created_at}</td> <td class="detailz" data-label="@lang('Details')">${value.details}</td> </tr>`); $("tbody").append(row); }); // 无数据时显示空状态 if(response.data.length === 0) { $("tbody").html('<tr><td colspan="100%" class="text-center justify-content-center">@lang("No data.")</td></tr>'); } }, error: function( xhr ){ console.log("请求错误:", xhr.responseText); } }); }, 5000); } // 页面加载完成后启动定时任务 $(document).ready(function() { updatePost(); });
额外优化建议
- 如果只需要新增数据,不需要每次清空表格,可以记录最后一条数据的
id,请求时传给控制器,只返回id大于该值的新数据,减少带宽消耗。 - 可以给AJAX请求添加loading状态,提升用户体验。
内容的提问来源于stack exchange,提问作者CodeEmpires
相关产品推荐
相关产品推荐

