我如何使用“ajax-event rowDblselect”嵌套数据表

时间:2012-12-14 13:54:07

标签: java jsf java-ee web-applications primefaces

我有一个数据表列出了子目录。我还有一个子数据表列出了submerchants的服务。我使用“p:rowExpansion”来显示服务数据表。当用户双击父数据表行(submerchant)时,我需要显示submerschant细节。此外,我需要在用户双击services datatble行时显示服务详细信息。如果我使用p:ajax event = rowDblselect用于submerchant表而ajax event = rowSelect用于services表,它可以正常工作。但是如果我对我想要做的两个数据表使用ajax event = rowDblselect它就会失败。我的代码如下所示;

     <p:dataTable id="subMerchantsDataTable" var="subM"
             value="#{subMerchantManagement.subMerchantList}"
             rowKey="#{subM.subMerchantId}"
             selection="#{subMerchantCommon.selectedSubMerchant}"
             selectionMode="single"
             style="width:1000;border: 1px solid rgb(168, 168, 168);"
             scrollRows="20" scrollable="true" liveScroll="true"
             scrollHeight="450"
             emptyMessage="#{messagebundle.submerc_grdlabel_no_submerchant}">

           <p:ajax event="rowToggle"
              listener="#{subMerchantManagement.onRowToggle}" width="100%" />

           <p:ajax event="rowDblselect"
              listener="#{subMerchantManagement.retrieveSubmerchantDetails}"
              update=":mainTabView"  />

           <p:column width="20" disabledSelection="true">
              <p:rowToggler />
           </p:column>

           <p:column headerText="#{messagebundle.submerc_columnHeader_id}"
              width="70" sortBy="#{subM.subMerchantId}">
              <h:outputText value="#{subM.subMerchantId}" />
           </p:column>
           ...........
           ...........
           <p:rowExpansion>
              <p:dataTable id="subMerchantServicesDataTable" var="svc"
                 value="#{subM.subMerchantServices}" rowKey="#{svc.serviceId}"
                 selection="#{subMerchantCommon.selectedService}"
                 selectionMode="single"
                 style="border: 1px solid rgb(168, 168, 168);" 
                 emptyMessage="#{messagebundle.submerc_grdlabel_no_service}">

                 <p:ajax event="rowSelect"
                    listener="#{subMerchantManagement.retrieveSubmerchantDetailsByService}"
                    update=":mainTabView" />

                 <p:column width="18">
                    <h:outputText value="-" />
                 </p:column>
                 <p:column width="70">
                    <h:outputText value="#{svc.serviceId}" />
                 </p:column>
                    ...........
                    ...........
              </p:dataTable>
         </p:rowExpansion>
   </p:dataTable>

当我对两个数据表使用ajax event = rowDblselect时。如果我双击服务数据表行,将显示详细信息页面,但是我从控制台捕获的异常如下所示;

`WARNING: Method not found: ........faces.bean.submerchants.SubMerchantManagement@1b0c025.retrieveSubmerchantDetailsByService(javax.faces.event.AjaxBehaviorEvent)
javax.el.MethodNotFoundException: Method not found: .........faces.bean.submerchants.SubMerchantManagement@1b0c025.retrieveSubmerchantDetailsByService(javax.faces.event.AjaxBehaviorEvent)
at com.sun.el.util.ReflectionUtil.getMethod(ReflectionUtil.java:155)
at com.sun.el.parser.AstValue.invoke(AstValue.java:231)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
at org.primefaces.component.behavior.ajax.AjaxBehaviorListenerImpl.processAjaxBehavior(AjaxBehaviorListenerImpl.java:47)
at javax.faces.event.AjaxBehaviorEvent.processListener(AjaxBehaviorEvent.java:113)
at javax.faces.component.behavior.BehaviorBase.broadcast(BehaviorBase.java:106)
at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:760)
at javax.faces.component.UIData.broadcast(UIData.java:1071)
at javax.faces.component.UIData.broadcast(UIData.java:1093)
at javax.faces.component.UIData.broadcast(UIData.java:1093)
at javax.faces.component.UIData.broadcast(UIData.java:1093)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3715)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3681)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2277)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2183)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)`

如果我双击submerchants datatable行,则无法显示详细信息页面(无法调用托管bean方法。)并且我从控制台捕获了相同的异常。看起来当我双击服务数据表行时,调用与submerchants datatable相关的方法,并再次抛出相同的异常。

有没有人有解决方案的想法?任何建议将被认真考虑。我想要嵌套数据表,并且当我单击每个数据的行时想要导航到细节。提前谢谢....

2 个答案:

答案 0 :(得分:1)

尝试将rowDblselect用于其中一个dataTable并手动侦听并通过jQuery触发dblClick事件以获取其他dataTable

答案 1 :(得分:0)

我做了一个快速测试,结果证明我有相同的结果。如果p:datatable的另一个p:datatable嵌套了与之绑定的相同事件,那么重复的事件将无法正常工作。

我还注意到,如果您从listener标记中删除p:ajax属性,则它基本上“有效”。

另一个问题是,由于某种原因,所选值会被null值覆盖。 “解决方法”是检查选择值的setter,如果它不为null。但是这些都是肮脏的解决方法,应报告错误; - )

工作示例:

Bean(至少应该是视图范围):

public class Bean
{
    private List<String> firstList = new ArrayList<String>();
    private List<String> secondList = new ArrayList<String>();
    private String selection;

    @PostConstruct
    private void init()
    {
        firstList.add("First item");
        firstList.add("Second item");
        secondList.add("Third item");
        secondList.add("Fourth item");
    }

    public void setSelection(String selection)
    {
        if (selection != null && !selection.isEmpty())
        this.selection = selection;
    }

    // Other getters/setters omitted
}

JSF:

<h:form>
    <p:dataTable value="#{bean.firstList}" var="first" rowKey="#{first}"
        selection="#{bean.selection}" selectionMode="single">
        <p:ajax event="rowSelect" update=":selectionPanel" />
        <p:column>
            <p:rowToggler />
        </p:column>
        <p:column>
            <h:outputText value="#{first}" />
        </p:column>
        <p:rowExpansion>
            <p:dataTable value="#{bean.secondList}" var="second"
                rowKey="#{second}" selection="#{bean.selection}"
                selectionMode="single">
                <p:ajax event="rowSelect" update=":selectionPanel" />
                <p:column>
                    <h:outputText value="#{second}" />
                </p:column>
            </p:dataTable>
        </p:rowExpansion>
    </p:dataTable>
</h:form>
<p:panel id="selectionPanel" header="Selection">
    <h:outputText value="#{bean.selection}" />
</p:panel>