实时搜索结果更新问题:EJS模板无法接收数据库返回数组
解决EJS模板无法实时更新搜索结果的问题
核心问题在于EJS是服务器端渲染模板,首次页面加载时会把数据注入模板生成静态HTML,之后前端的输入操作是在浏览器端执行的,后端无法主动重新渲染模板并更新页面。正确的做法是用「前端异步请求+DOM动态更新」替代后端重新渲染模板。
1. 调整后端接口(server.js)
拆分路由:一个负责初始页面渲染,一个负责处理搜索请求并返回JSON数据:
// 初始页面渲染,首次加载时返回空数组的EJS页面 app.get('/search', (req, res) => { res.render('search', { array: [] }); }); // 搜索接口:接收关键词,查询数据库后返回JSON格式的结果 app.get('/api/search', (req, res) => { const keyword = req.query.keyword || ''; // 这里替换成你的数据库查询逻辑,注意防SQL注入 db.query( 'SELECT * FROM STUDENT WHERE name LIKE ? OR id LIKE ?', [`%${keyword}%`, `%${keyword}%`], (err, results) => { if (err) { console.error(err); return res.status(500).json([]); } res.json(results); // 返回JSON数据给前端 } ); });
2. 前端实现实时搜索与表格更新(script.js)
监听输入框的input事件,发送异步请求获取数据,然后动态修改表格内容(加入防抖避免频繁请求):
const searchInput = document.getElementById('search-input'); const tableBody = document.querySelector('#result-table tbody'); // 防抖函数:减少频繁请求 function debounce(fn, delay) { let timer; return function(...args) { clearTimeout(timer); timer = setTimeout(() => fn.apply(this, args), delay); }; } // 监听输入事件 searchInput.addEventListener('input', debounce(async function() { const keyword = this.value.trim(); try { // 发送GET请求到搜索接口 const response = await fetch(`/api/search?keyword=${encodeURIComponent(keyword)}`); const students = await response.json(); // 清空表格现有内容 tableBody.innerHTML = ''; if (students.length === 0) { // 无数据时显示提示 tableBody.innerHTML = '<tr><td colspan="3">未找到匹配的学生</td></tr>'; return; } // 遍历数据生成表格行 students.forEach(student => { const row = document.createElement('tr'); row.innerHTML = ` <td>${student.id}</td> <td>${student.name}</td> <td>${student.age}</td> <!-- 根据你的表结构添加其他字段 --> `; tableBody.appendChild(row); }); } catch (err) { console.error('搜索失败:', err); tableBody.innerHTML = '<tr><td colspan="3">搜索出错,请重试</td></tr>'; } }, 300)); // 300ms防抖延迟
3. 调整EJS页面(search.ejs)
保留初始的空表格结构,无需依赖后端注入的array来渲染(初始提示可自定义):
<!DOCTYPE html> <html> <head> <title>学生搜索</title> </head> <body> <input type="text" id="search-input" placeholder="输入姓名/ID搜索学生"> <table id="result-table" border="1"> <thead> <tr> <th>ID</th> <th>姓名</th> <th>年龄</th> </tr> </thead> <tbody> <tr><td colspan="3">请输入关键词开始搜索</td></tr> </tbody> </table> <script src="/script.js"></script> </body> </html>
为什么原来的方式无效?
你之前的逻辑试图让后端在每次搜索时重新渲染EJS模板,但EJS的渲染是一次性的——只有当浏览器发起新的页面请求时,后端才会生成新的HTML返回。而前端输入事件属于页面内操作,不会触发新的页面请求,所以模板里的array始终是首次渲染时的空值。
内容的提问来源于stack exchange,提问作者kimo02
相关产品推荐
相关产品推荐

