PrimeFaces ajax rowSelect事件oncomplete参数id为空的原因与解决
问题代码
<h:form id="form"> <p:dataTable var="article" value="#{articleTable.articles}" lazy="true" selection="#{articleTable.selected}" selectionMode="single" emptyMessage="#{text['emptyMessage']}" rowKey="#{article.id}"> <p:column style="display:none;"> <h:outputText value="#{article.id}" /> </p:column> <p:column headerText="#{text['titleText']}"> <h:outputText value="#{article.title}" /> </p:column> <p:column headerText="#{text['summaryText']}"> <h:outputText value="#{article.summary}" /> </p:column> <p:column headerText="#{text['categoryText']}"> <h:outputText value="#{article.category}" /> </p:column> <p:column headerText="#{text['statusText']}"> <h:outputText value="#{article.status.text}" /> </p:column> <p:ajax event="rowSelect" oncomplete="handleRowSelect('#{article.id}')"/> </p:dataTable> </h:form>
<script type="text/javascript"> function handleRowSelect(id) { if ( id ) window.location.href = 'article.xhtml?id=' + id; } </script>
问题原因
直接在<p:ajax>的oncomplete中使用#{article.id}无效,因为*var="article"*的作用域仅局限于<p:column>内部。<p:ajax>是绑定在<p:dataTable>上的组件,不在列的作用域范围内,服务器渲染页面时无法找到当前行对应的article对象,导致传递给handleRowSelect的参数为空。
修复方案
以下两种方式都能解决问题,按需选择:
方式一:客户端直接获取选中行数据
给<p:dataTable>添加widgetVar属性,通过PrimeFaces组件实例直接获取选中行ID:
<p:dataTable var="article" value="#{articleTable.articles}" lazy="true" selection="#{articleTable.selected}" selectionMode="single" emptyMessage="#{text['emptyMessage']}" rowKey="#{article.id}" widgetVar="articleTableWidget"> <!-- 新增widgetVar属性 --> <!-- 列代码保持不变 --> <p:ajax event="rowSelect" oncomplete="handleRowSelect(PF('articleTableWidget').getSelectedRowData().id)"/> </p:dataTable>
这种方式无需修改后台代码,完全在客户端完成ID获取。
方式二:后台传递参数到客户端
通过<p:ajax>的listener方法,在后台将选中行的ID传递给客户端:
- 修改
<p:ajax>标签:
<p:ajax event="rowSelect" listener="#{articleTable.onRowSelect}" oncomplete="handleRowSelect(articleId)"/>
- 在
ArticleTable后台Bean中实现onRowSelect方法:
import org.primefaces.event.SelectEvent; import org.primefaces.context.RequestContext; import your.package.Article; // 替换为实际的Article类包路径 public class ArticleTable { // 其他已有代码 public void onRowSelect(SelectEvent<Article> event) { Article selectedArticle = event.getObject(); RequestContext.getCurrentInstance().addCallbackParam("articleId", selectedArticle.getId()); } }
后台会将articleId作为回调参数传递给客户端,oncomplete中直接使用该变量即可。
常见疑问解答
- 不需要使用
commandLink或commandButton,通过点击行完全可以实现页面跳转,上述两种方案都能达成需求。 - 点击行跳转的逻辑是可行的,只要正确获取选中行的ID,就能通过
window.location.href跳转到目标页面。
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

