Laravel页面刷新后保留动态生成表格的技术实现问询
解决Laravel中动态生成表格刷新后消失的方案
核心思路:动态生成的表格仅存在于当前页面内存中,页面刷新后DOM会重置,因此需要将表格数据持久化到数据库,页面加载时从数据库读取数据并自动渲染为只读表格。
一、后端实现(Controller与模型调整)
1. 创建数据库迁移与模型
首先创建存储表格数据的表,用JSON类型存储每行数据:
迁移文件(database/migrations/xxxx_xx_xx_create_grading_computations_table.php)
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up() { Schema::create('grading_computations', function (Blueprint $table) { $table->id(); $table->foreignId('user_id')->constrained()->onDelete('cascade'); $table->json('rows'); // 存储表格行数据 $table->timestamps(); }); } public function down() { Schema::dropIfExists('grading_computations'); } };
模型文件(app/Models/GradingComputation.php)
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class GradingComputation extends Model { use HasFactory; protected $fillable = ['user_id', 'rows']; protected $casts = [ 'rows' => 'array', // 自动将JSON转为数组 ]; }
2. 控制器代码(app/Http/Controllers/GradingController.php)
<?php namespace App\Http\Controllers; use App\Models\GradingComputation; use Illuminate\Http\Request; class GradingController extends Controller { // 显示页面,同时传递已保存的表格数据 public function index() { $savedData = GradingComputation::where('user_id', auth()->id())->first(); return view('grading.index', [ 'savedGrading' => $savedData ? $savedData->rows : null ]); } // 保存表格数据到数据库 public function store(Request $request) { $request->validate([ 'table_rows' => 'required|array', 'table_rows.*.column1' => 'required', 'table_rows.*.column2' => 'required', 'table_rows.*.column3' => 'required', // 根据实际表格列调整验证规则 ]); // 存在则更新,不存在则创建 GradingComputation::updateOrCreate( ['user_id' => auth()->id()], ['rows' => $request->table_rows] ); return response()->json(['success' => true]); } }
3. 路由配置(routes/web.php)
Route::get('/grading', [GradingController::class, 'index'])->name('grading.index'); Route::post('/grading/save', [GradingController::class, 'store'])->name('grading.save');
二、前端实现(视图与jQuery代码)
1. 主视图(resources/views/grading/index.blade.php)
<div class="container mt-4"> <div class="mb-3"> <label for="rowCount" class="form-label">输入表格行数:</label> <input type="number" id="rowCount" class="form-control" min="1" value="1" {{ $savedGrading ? 'disabled' : '' }}> <button id="createTable" class="btn btn-primary mt-2" {{ $savedGrading ? 'style=display:none' : '' }}>创建表格</button> </div> <div id="tableContainer"> <!-- 已保存的表格直接渲染为只读状态 --> @if($savedGrading) @include('grading.readonly-table', ['rows' => $savedGrading]) @endif </div> <button id="saveBtn" class="btn btn-success mt-3" {{ $savedGrading ? 'style=display:none' : '' }}>Save grading computation</button> </div> <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script> <script> $(document).ready(function() { let isTableSaved = {{ $savedGrading ? 'true' : 'false' }}; // 创建表格按钮逻辑 $('#createTable').click(function() { if (isTableSaved) return; let rowCount = parseInt($('#rowCount').val()); if (isNaN(rowCount) || rowCount < 1) { alert('请输入有效的行数'); return; } // 生成可编辑表格 let tableHtml = '<table class="table table-bordered"><thead><tr><th>列1</th><th>列2</th><th>列3</th></tr></thead><tbody>'; for (let i=0; i<rowCount; i++) { tableHtml += `<tr> <td><input type="text" class="form-control table-input" data-column="column1"></td> <td><input type="text" class="form-control table-input" data-column="column2"></td> <td><input type="text" class="form-control table-input" data-column="column3"></td> </tr>`; } tableHtml += '</tbody></table>'; $('#tableContainer').html(tableHtml); }); // 保存按钮逻辑 $('#saveBtn').click(function() { if (!$('#tableContainer table').length) { alert('请先创建表格并填写数据'); return; } // 收集表格数据 let tableRows = []; $('#tableContainer table tbody tr').each(function() { let rowData = {}; $(this).find('.table-input').each(function() { rowData[$(this).data('column')] = $(this).val().trim(); }); tableRows.push(rowData); }); // 提交到后端保存 $.ajax({ url: '{{ route('grading.save') }}', method: 'POST', data: { _token: '{{ csrf_token() }}', table_rows: tableRows }, success: function() { // 转为只读表格 $('#tableContainer table tbody tr').each(function(index) { let row = tableRows[index]; $(this).html(` <td>${row.column1}</td> <td>${row.column2}</td> <td>${row.column3}</td> `); }); // 隐藏操作按钮,标记为已保存 $('#saveBtn, #createTable').hide(); $('#rowCount').prop('disabled', true); isTableSaved = true; }, error: function() { alert('保存失败,请重试'); } }); }); }); </script>
2. 只读表格局部视图(resources/views/grading/readonly-table.blade.php)
<table class="table table-bordered"> <thead> <tr> <th>列1</th> <th>列2</th> <th>列3</th> </tr> </thead> <tbody> @foreach($rows as $row) <tr> <td>{{ $row['column1'] }}</td> <td>{{ $row['column2'] }}</td> <td>{{ $row['column3'] }}</td> </tr> @endforeach </tbody> </table>
关键说明
- 数据持久化:通过JSON字段存储每行数据,关联当前登录用户,确保数据隔离;
- 初始化渲染:页面加载时自动检查已保存数据,存在则直接渲染只读表格;
- 状态控制:用
isTableSaved变量标记保存状态,避免重复创建或保存操作; - 前后端验证:后端对提交数据做合法性校验,前端做基础交互校验。
内容的提问来源于stack exchange,提问作者CaptainCRAZY
相关产品推荐
相关产品推荐

