JSF+Spring环境下JS无法获取Bean更新后属性值的问题
问题根源分析
你遇到的核心问题是JSF EL表达式的执行时机:#{configuracionBean.edicion}是服务器端渲染页面时执行的,它会把当时Bean的属性值转换成静态的true或false字符串嵌入到JavaScript代码里。页面发送到浏览器后,这段JS代码就固定了,后续后端Bean的属性变化,浏览器里的JS根本感知不到——因为它拿到的是页面加载时的旧值。
解决方案
下面是几种实用的解决方式,根据你的场景选就行:
1. 用AJAX更新JS代码区域
把你的JS代码放在可被AJAX渲染的JSF组件里,每次切换Bean属性时,让服务器重新生成这段JS,把最新的属性值传过来。
示例代码:
<!-- 触发属性切换的按钮,通过AJAX更新JS代码所在区域 --> <h:commandButton value="切换编辑状态" action="#{configuracionBean.toggleEdicion}"> <f:ajax render="scriptEdicion" /> </h:commandButton> <!-- 将JS代码放在带id的outputScript中,方便AJAX定位更新 --> <h:outputScript id="scriptEdicion"> var editarNuevo = #{configuracionBean.edicion}; if(!editarNuevo){ alert(editarNuevo); dialog.classList.add('large'); document.getElementById("titleSpan").textContent="#{etiquetas['configuracionP.editar']}"; }else{ alert(editarNuevo); dialog.classList.remove('large'); } </h:outputScript>
2. 让JS主动调用后端获取最新值
通过JSF的h:commandScript定义一个可被JS调用的后端方法,需要时主动获取最新的属性值,不依赖页面加载时的静态值。
第一步:在Bean中添加获取属性的方法
@Named @ViewScoped public class ConfiguracionBean implements Serializable { private boolean edicion; // 切换属性的方法 public void toggleEdicion() { this.edicion = !this.edicion; } // 供JS调用的属性获取方法 public boolean getCurrentEdicion() { return this.edicion; } }
第二步:页面中定义可被JS调用的命令脚本
<h:commandScript name="getEdicionValue" action="#{configuracionBean.currentEdicion}" render="@none" return="editarNuevo" />
第三步:JS中主动调用获取最新值
// 当需要使用最新值时,调用这个方法 var editarNuevo = getEdicionValue(); if(!editarNuevo){ alert(editarNuevo); dialog.classList.add('large'); document.getElementById("titleSpan").textContent="#{etiquetas['configuracionP.editar']}"; }else{ alert(editarNuevo); dialog.classList.remove('large'); }
3. AJAX回调中手动同步状态
如果只是简单的布尔值切换,也可以在AJAX成功回调里直接翻转JS变量的值,省得再调用后端。
示例代码:
<h:commandButton value="切换编辑状态" action="#{configuracionBean.toggleEdicion}"> <f:ajax execute="@this" render="@none" onevent="handleToggle" /> </h:commandButton>
// 页面加载时的初始值 var editarNuevo = #{configuracionBean.edicion}; function handleToggle(data) { // AJAX请求成功后执行 if (data.status === 'success') { // 直接翻转变量值,和后端同步 editarNuevo = !editarNuevo; // 执行你的逻辑 if(!editarNuevo){ alert(editarNuevo); dialog.classList.add('large'); document.getElementById("titleSpan").textContent="#{etiquetas['configuracionP.editar']}"; }else{ alert(editarNuevo); dialog.classList.remove('large'); } } }
内容的提问来源于stack exchange,提问作者Javier Medina Rodríguez
相关产品推荐
相关产品推荐

