CakePHP 3.6.14:Ajax表单提交后重新加载BootstrapTable内容
我来帮你搞定这个问题!你遇到的$('#table').bootstrapTable('refresh')无效的核心原因是:当前的表格是通过PHP后端直接渲染静态HTML生成的,没有配置BootstrapTable的远程数据源。BootstrapTable的refresh方法默认是用来请求远程接口获取新数据并重新渲染表格的,如果没有指定data-url,它不知道从哪里拉取更新后的数据,自然不会生效。
下面给你两种可行的解决方案,你可以根据自己的需求选择:
方案一:配置远程数据源(推荐)
这种方式是BootstrapTable的标准用法,把表格数据的加载交给组件自己处理,后续的刷新、分页、排序都会更省心。
1. 修改BootstrapTable的HTML结构
去掉原来手动渲染的<tbody>,添加data-url属性指向获取任务列表的接口,同时可以配置服务器端分页(如果需要的话):
<table class="table-striped" id="table" data-toggle="table" data-search="true" data-filter-control="true" data-click-to-select="true" data-escape="false" data-url="/app/tasks/getTasks" <!-- 新增:指定数据接口 --> data-side-pagination="server"> <!-- 可选:如果需要服务器端分页 --> <thead> <tr> <th data-field="name" data-filter-control="input" data-sortable="true" data-sorter="linksSorter" scope="col"><?= __('Title') ?></th> </tr> </thead> <!-- 这里不再需要手动写tbody,BootstrapTable会自动生成 --> </table>
2. 后端新增获取任务列表的接口
在Tasks控制器里添加getTasks方法,返回BootstrapTable需要的JSON格式数据:
public function getTasks() { $this->viewBuilder()->layout(false); $this->autoRender = false; // 查询所有任务 $tasks = $this->Tasks->find('all')->toArray(); // 组装成BootstrapTable要求的格式(如果是服务器端分页,需要包含total字段) $responseData = [ 'total' => count($tasks), 'rows' => $tasks ]; $this->response->type('json'); return json_encode($responseData); }
3. 调整前端提交成功后的逻辑
现在refresh方法会自动请求data-url对应的接口,重新加载并渲染表格:
$(function () { $("#DAbtn").click(function () { var input = $("<input>") .attr("type", "hidden") .attr("name", "btn").val("Direct Assign"); $('#newTaskForm').append(input); var task = $("#newTaskForm").serialize(); $.ajax({ type: 'POST', url: '/app/tasks/createTask', datatype: 'json', data: task, success: function( data ) { $('.modal').modal('hide'); $(".success").fadeIn(500).delay(2000).fadeOut(500); $("#newTaskForm")[0].reset(); clearForm("newTaskForm"); // 现在refresh会正常工作了 $('#table').bootstrapTable('refresh'); } }); return false; }); });
方案二:手动添加新行(适合简单场景)
如果不想改动太多现有代码,也可以在表单提交成功后,直接把新创建的任务添加到表格中:
1. 修改后端createTask接口返回数据
在创建任务成功后,返回新任务的信息:
public function createTask($userid = null, $projectid = null, $copiedtaskid = null) { $this->viewBuilder()->layout(false); $this->autoRender = false; $http = new Client(); $task = $this->Tasks->newEntity(); if ($this->request->is('ajax')) { // 你的任务创建逻辑... // 假设$task是创建成功后的实体 $this->response->type('json'); return json_encode(['task' => $task]); // 返回新任务数据 } $this->response->statusCode(200); return $this->response; }
2. 前端手动添加新行
在AJAX成功回调里,用append方法把新任务添加到表格:
success: function( data ) { $('.modal').modal('hide'); $(".success").fadeIn(500).delay(2000).fadeOut(500); $("#newTaskForm")[0].reset(); clearForm("newTaskForm"); // 手动添加新行到表格 $('#table').bootstrapTable('append', [{ id: data.task.id, name: `<a href="/app/tasks/edit/${data.task.id}" data-target="#exampleFormModal" data-toggle="modal">${data.task.name}</a>` }]); }
为什么原来的refresh无效?
你最初的表格是通过PHP循环生成静态<tr>,BootstrapTable初始化时只是基于现有DOM做了增强,但没有绑定远程数据源。refresh方法的设计初衷是让组件重新请求接口获取最新数据,没有配置data-url的话,它没有数据源可以刷新,所以不会有任何变化。
内容的提问来源于stack exchange,提问作者dvn22

