PrimeFaces中Ajax更新Bean属性后JS无法获取最新值的问题
解决PrimeFaces Ajax更新后JavaScript无法获取最新Bean属性的问题
这个问题我之前也碰到过,核心原因其实是EL表达式的执行时机和Ajax组件的渲染范围没搞清楚,咱们一步步拆解解决:
为什么原来的代码不生效?
- 你JS里的
#{backController.productViewerUrl}是在页面第一次渲染时由服务器解析的,Ajax请求完成后不会重新解析这个EL,所以它永远是页面加载时的初始值,和Bean更新后的新值无关。 - 虽然你在Bean里更新了
productViewerUrl,但<p:ajax>默认不会重新渲染那个隐藏字段,所以客户端DOM里的隐藏字段值还是旧的,$('#pbm\\:hutchy').val()自然拿不到新值。
两种靠谱的解决办法
方法一:让Ajax重新渲染隐藏字段
只需要给<p:ajax>加上update属性,指定要更新的隐藏字段ID,这样Ajax执行完后,服务器会把更新后的隐藏字段值同步到客户端DOM:
<!-- 给p:ajax添加update属性,指定隐藏字段的ID --> <p:ajax event="rowDblselect" listener="#{backController.onRowDoubleClick}" update="hutchy" oncomplete="openNewTab()" /> <h:inputHidden id="hutchy" value="#{backController.productViewerUrl}" />
然后简化你的JavaScript方法,直接取更新后的隐藏字段值就行:
function openNewTab(){ var url = $('#pbm\\:hutchy').val(); alert(url); window.open(url, '_newtab'); }
方法二:通过Ajax回调参数直接传递值(更推荐)
这种方式不需要依赖隐藏字段,直接把更新后的URL通过PrimeFaces的Ajax回调参数传给JS,更简洁高效:
首先修改Bean的监听方法,把URL添加到Ajax回调参数中:
public void onRowDoubleClick(final SelectEvent event) { RecordDTO currentRecordDTO = (RecordDTO) event.getObject(); String url = "https://www.google.com/search?q=" + currentRecordDTO.getName(); setProductViewerUrl(url); // 把URL添加到Ajax回调参数 PrimeFaces.current().ajax().addCallbackParam("productUrl", url); }
然后修改JavaScript方法,接收回调参数:
function openNewTab(xhr, status, args){ // 从args里直接拿到服务器传过来的新URL var url = args.productUrl; alert(url); window.open(url, '_newtab'); }
最后更新<p:ajax>的oncomplete,传递回调参数:
<p:ajax event="rowDblselect" listener="#{backController.onRowDoubleClick}" oncomplete="openNewTab(xhr, status, args)" />
总结
方法一适合需要在多个地方复用这个隐藏字段值的场景;方法二更直接,减少DOM依赖,是PrimeFaces Ajax传递数据的标准做法,推荐优先使用。
内容的提问来源于stack exchange,提问作者Sentary
相关产品推荐
相关产品推荐

