JSF复合组件中Primefaces SelectEvent无法找到Bean方法
JSF复合组件中Ajax dialogReturn事件无法调用Bean方法的问题
我正在为项目开发自定义复合组件,组件包含触发独立模态框搜索的按钮,以及接收SelectEvent的方法,用于处理用户选择的值并设置到Bean中。但目前遇到的问题是,复合组件无法找到Ajax对话框返回对应的Bean方法。
使用环境:JSF 2.3 + Primefaces 10.0.0
复合组件inputConverter.xhtml代码
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns = "http://www.w3.org/1999/xhtml" xmlns:composite = "http://java.sun.com/jsf/composite" xmlns:p="http://primefaces.org/ui"> <composite:interface> <composite:attribute name = "labelValue" required="true"/> <composite:attribute name = "inputId" required="true"/> <composite:attribute name = "inputValue" required="true"/> <composite:attribute name = "inputObject" required="true"/> <composite:attribute name = "limpaAction" method-signature="void limpaAction()" required="true"/> <composite:attribute name = "buscaAction" method-signature="void buscaAction()" required="true"/> <composite:attribute name = "retornoAction" method-signature="void retornoAction(org.primefaces.event.SelectEvent)" /> </composite:interface> <composite:implementation> <p:panelGrid columns="1"> <p:outputLabel for="@next" value="#{cc.attrs.labelValue}"/> <p:panelGrid columns="3" styleClass="ui-inputgroup"> <p:inputText value="#{cc.attrs.inputValue}" readonly="true"/> <p:commandButton action="#{cc.attrs.limpaAction}" rendered="#{not empty cc.attrs.inputObject}" update="@parent" icon="pi pi-trash" styleClass="ui-button-danger"/> <p:commandButton action="#{cc.attrs.buscaAction}" icon="pi pi-search" styleClass="ui-button-info" > <p:ajax event="dialogReturn" listener="#{cc.attrs.retornoAction}" update="@parent"/> </p:commandButton> </p:panelGrid> </p:panelGrid> </composite:implementation> </html>
主页面调用方式
<custom:inputConverter labelValue="País" inputObject="#{pacienteBean.paciente.paisNacionalidade}" inputId="#{pacienteBean.paciente.paisNacionalidade.id}" inputValue="#{pacienteBean.paciente.paisNacionalidade.nome}" buscaAction="#{pacienteBean.buscaNacionalidade}" retornoAction="#{pacienteBean.selecionaNacionalidade}" limpaAction="#{pacienteBean.limpaNacionalidade}" />
Bean中的目标方法
public void selecionaNacionalidade(SelectEvent<Pais> e) { objetoCrud.setPaisNacionalidade(e.getObject()); }
直接在复合组件中调用#{pacienteBean.selecionaNacionalidade}可正常工作,但通过复合属性调用时失败,修改retornoAction的method-signature也无效。选择搜索对话框值时,会抛出javax.el.PropertyNotFoundException等错误。
临时解决方案
通过添加p:remoteCommand、创建会话级BuscaBean中转事件对象解决,具体步骤如下:
- 在inputConverter.xhtml中添加远程命令:
<p:remoteCommand name="#{cc.id}" action="#{cc.attrs.retornoAction}" immediate="true"/>
- 修改dialogReturn的Ajax监听:
<p:ajax event="dialogReturn" listener="#{buscaBean.resultadoPesquisaInputConverter}" oncomplete="#{cc.id}()"/>
- 创建BuscaBean.java:
public static <T> void resultadoPesquisaInputConverter(SelectEvent<T> event) { objetoSelecionado = event.getObject(); }
- 修改Bean中的方法:
@Inject private BuscaBean buscaBean; public void selecionaNacionalidade() { objetoCrud.setPaisNacionalidade(buscaBean.getResultadoPesquisa(Pais.class)); }
- 修改后的组件调用:
<custom:inputConverter labelValue="País" inputObject="#{pacienteBean.paciente.paisNacionalidade}" inputId="#{pacienteBean.paciente.paisNacionalidade.id}" inputValue="#{pacienteBean.paciente.paisNacionalidade.nome}" buscaAction="#{buscaBean.abrirBuscaPaises}" retornoAction="#{pacienteBean.selecionaNacionalidade}" limpaAction="#{pacienteBean.limpaNacionalidade}" />
内容的提问来源于stack exchange,提问作者Guilherme Pereira
相关产品推荐
相关产品推荐

