页面多表单问题:creationForm未显示对应模板值,残留上次AJAX数据
问题分析与解决方案
首先得明确问题的核心:你的creationForm是页面初始化时就渲染完成并隐藏的,它的字段值是第一次加载页面时从Session中获取的旧数据。当你通过同步AJAX更新Session后,页面并没有主动重新获取最新的TemplateBean数据来更新表单字段,所以显示的还是上一次的旧值。
下面给出两种针对性的解决方案,你可以根据实际场景选择:
方案1:异步AJAX+动态填充表单字段(推荐,体验更好)
这种方式不需要重新加载页面,直接用后台返回的最新数据更新表单字段,避免同步AJAX的浏览器阻塞问题。
步骤1:修改Servlet,返回TemplateBean的JSON数据
当operationName为submitButtonClicked时,查询到TemplateBean后,除了存入Session,还要将其序列化为JSON格式返回给前端(可以用Jackson/Gson这类工具库):
// 假设已获取到templateBean ObjectMapper mapper = new ObjectMapper(); String templateJson = mapper.writeValueAsString(templateBean); response.setContentType("application/json;charset=utf-8"); response.getWriter().write(templateJson);
步骤2:修改前端JS逻辑,异步请求+动态更新表单
function submitButton() { // 获取下拉框选中的模板名(请根据实际下拉框选择器调整) var templateName = $("#myForm select[name='templateName']").val(); $.ajax({ async: true, // 改为异步,避免阻塞浏览器 cache: false, url: "changeCreation.do", method: "post", data: { "operationName": "submitButtonClicked", "templateNameVal": templateName }, dataType: "json", success: function (templateBean) { // 根据返回的最新数据,逐个更新creationForm的字段 $("#creationForm input[name='field1']").val(templateBean.field1); $("#creationForm input[name='field2']").val(templateBean.field2); // 其他字段以此类推... // 字段更新完成后,再显示表单 $("#creationForm").show(); $("#create").show(); }, error: function() { alert("加载模板数据失败,请重试"); } }); } // 页面初始化逻辑简化 $(document).ready(function () { $("#creationForm").hide(); $("#create").hide(); $("#submit").click(function() { submitButton(); return false; // 阻止表单默认提交行为 }); });
方案2:AJAX重新加载表单HTML片段(适合字段较多的场景)
如果creationForm的字段非常多,手动逐个赋值太麻烦,可以让后台返回渲染好的最新表单HTML,前端直接替换原有表单。
步骤1:修改Servlet,新增获取表单HTML的逻辑
在changeCreation.do中添加一个新的operationName分支,用于返回渲染后的表单:
if ("getCreationForm".equals(operationName)) { TemplateBean templateBean = (TemplateBean) session.getAttribute("templateBean"); // 这里可以用JSP模板引擎或字符串拼接渲染表单(实际项目建议用JSP include或模板引擎) StringWriter formHtmlWriter = new StringWriter(); formHtmlWriter.write("<form action='changeCreation.do' method='post' id='creationForm'>"); formHtmlWriter.write("<input type='text' name='field1' value='" + templateBean.getField1() + "'>"); // 其他字段... formHtmlWriter.write("</form>"); response.setContentType("text/html;charset=utf-8"); response.getWriter().write(formHtmlWriter.toString()); }
步骤2:修改前端JS,先提交模板选择,再加载最新表单
function submitButton() { var templateName = $("#myForm select[name='templateName']").val(); // 第一步:提交模板选择,更新Session中的TemplateBean $.ajax({ async: true, cache: false, url: "changeCreation.do", method: "post", data: { "operationName": "submitButtonClicked", "templateNameVal": templateName }, success: function () { // 第二步:请求获取最新渲染的表单HTML $.ajax({ url: "changeCreation.do", method: "post", data: { "operationName": "getCreationForm" }, success: function(formHtml) { // 替换原有表单 $("#creationForm").replaceWith(formHtml); // 显示表单和按钮 $("#creationForm").show(); $("#create").show(); } }); } }); } // 页面初始化逻辑同方案1 $(document).ready(function () { $("#creationForm").hide(); $("#create").hide(); $("#submit").click(function() { submitButton(); return false; }); });
为什么原来的逻辑会出问题?
原来的流程是:点击按钮后先执行同步AJAX更新Session,然后直接显示页面初始化时就存在的creationForm。但这个表单的字段值是页面第一次加载时从Session获取的旧数据,Session更新后页面不会自动刷新这些字段,所以显示的还是上一次的内容。另外,同步AJAX会阻塞浏览器,用户体验很差,不建议使用。
内容的提问来源于stack exchange,提问作者Just Another Developer
相关产品推荐
相关产品推荐

