3

当我在复合表中定义 2 个 actionListener 时,第一个 actionListener 将在我单击它时被调用两次,但第二个监听器工作正常而没有问题。即使我切换了 2 个听众,第一个总是叫了两次,第二个很好。

这是xhtml:

    <!DOCTYPE html>

    <html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:asias="http://java.sun.com/jsf/composite/components/asias"
      xmlns:test="http://java.sun.com/jsf/composite/test">

    <h:head />
    <h:body>
      <h:form id="communityMembersForm">
        <test:outertable list="#{memberController.members}"
          title="Nested Table Test">
          <f:actionListener for="sortAction"
            binding="#{memberController.sortActionListener}" />
          <f:actionListener for="actions"
            binding="#{memberController.actionsActionListener}" />
        </test:outertable> 
      </h:form>
    </h:body>
    </html>

MemberController 是一个 viewScoped 托管 bean。外部表定义为:

    <!DOCTYPE html>

    <html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
      xmlns:composite="http://java.sun.com/jsf/composite"
      xmlns:test="http://java.sun.com/jsf/composite/test"
      xmlns:asias="http://java.sun.com/jsf/composite/components/asias">

    <composite:interface>
      <composite:attribute name="list" required="true" />
      <composite:attribute name="title" required="true" />
      <composite:actionSource name="sortAction" targets="communityMembersPage" />
      <composite:actionSource name="actions" targets="communityMembersPage" />
    </composite:interface>

    <composite:implementation>
      <div>
        <h3>#{cc.attrs.title}</h3>
        <asias:memberTable id="communityMembersPage" memberList="#{cc.attrs.list}"
          showPhone="true" showRoles="true" showAffiliation="true"
          showLastLoginDate="true" showActions="true" allowSortLastName="true"
          allowSortFirstName="true" allowSortEmail="true" />
      </div>
    </composite:implementation>
    </html>

memberTable 定义为:

    <!DOCTYPE html>

    <html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
      xmlns:composite="http://java.sun.com/jsf/composite">

    <composite:interface name="memberTable"
      displayName="A table for members of a community">
      <composite:attribute name="memberList" required="true" />
      <composite:attribute name="showPhone" type="java.lang.Boolean" default="false" />
      <composite:attribute name="showRoles" type="java.lang.Boolean" default="false" />
      <composite:attribute name="showAffiliation" type="java.lang.Boolean"
        default="false" />
      <composite:attribute name="showLastLoginDate" type="java.lang.Boolean"
        default="false" />
      <composite:attribute name="showActions" type="java.lang.Boolean"
        default="false" />
      <composite:attribute name="allowSortLastName" type="java.lang.Boolean"
        default="false" />
      <composite:attribute name="allowSortFirstName" type="java.lang.Boolean"
        default="false" />
      <composite:attribute name="allowSortEmail" type="java.lang.Boolean"
        default="false" />
      <composite:actionSource name="sortAction"
        targets="dataTable:sortLastName dataTable:sortFirstName dataTable:sortEmail" />
      <composite:actionSource name="actions" targets="dataTable:actions" />
    </composite:interface>

    <composite:implementation>
      <div id="#{cc.clientId}" class="member-table">
        <h:dataTable id="dataTable" value="#{cc.attrs.memberList}" var="member"
          rowClasses="odd,even"
          columnClasses="column1,column2,column3,column4,column5,column6,column7">
          <h:column>
            <f:facet name="header">
              <h:commandLink id="sortLastName"
                rendered="#{cc.attrs.allowSortLastName}">
                <f:attribute name="sortBy" value="lastName" />
                <span>#{i18n['last-name']}</span>
              </h:commandLink>
              <h:outputText rendered="#{not cc.attrs.allowSortLastName}"
                value="#{i18n['last-name']}" />
            </f:facet>
            <span class='#{member.invalid ? "warning" : "" }'>#{member.lastName}</span>
          </h:column>
          <h:column>
            <f:facet name="header">
              <h:commandLink id="sortFirstName"
                rendered="#{cc.attrs.allowSortFirstName}">
                <f:attribute name="sortBy" value="firstName" />
                <span>#{i18n['first-name']}</span>
              </h:commandLink>
              <h:outputText rendered="#{not cc.attrs.allowSortFirstName}"
                value="#{i18n['first-name']}" />
            </f:facet>
            <span class='#{member.invalid ? "warning" : "" }'>#{member.firstName}</span>
          </h:column>
          <h:column>
            <f:facet name="header">
                      <h:commandLink id="sortEmail"
                rendered="#{cc.attrs.allowSortEmail}">
                <f:attribute name="sortBy" value="email" />
                <span>#{i18n['email-address']}</span>
              </h:commandLink>
              <h:outputText rendered="#{not cc.attrs.allowSortEmail}"
                value="#{i18n['email-address']}" />
            </f:facet>
            <span class='#{member.invalid ? "warning" : "" }'>#{member.email}</span>
          </h:column>
          <h:column
            rendered="#{cc.attrs.showPhone and loginUser.allowedToViewPhone}">
            <f:facet name="header">#{i18n['phone-number']}</f:facet>
            <span class='#{member.invalid ? "warning" : "" }'>#{member.phoneNumber}</span>
          </h:column>
          <h:column
            rendered="#{cc.attrs.showRoles and loginUser.allowedToViewRoles}">
            <f:facet name="header">#{i18n['roles']}</f:facet>
            <span class='#{member.invalid ? "warning" : "" }'> <ui:repeat
                value="#{member.roles}" var="role" varStatus="roleStatus">
                <h:outputText rendered="#{roleStatus.index > 0}" value=", " />
              #{role}
            </ui:repeat>
            </span>
          </h:column>
          <h:column
            rendered="#{cc.attrs.showAffiliation and loginUser.allowedToViewAffiliation}">
            <f:facet name="header">#{i18n['user-affiliation']}</f:facet>
            <span class='#{member.invalid ? "warning" : "" }'>#{member.userAffiliation}</span>
          </h:column>
          <h:column
            rendered="#{cc.attrs.showLastLoginDate and loginUser.allowedToViewLastLoginDate}">
            <f:facet name="header">#{i18n['last-login-date']}</f:facet>
            <h:outputText styleClass='#{member.invalid ? "warning" : "" }'
              value="#{member.lastLoginDate}" converter="#{dateToWeeksOldConverter}" />
          </h:column>
          <h:column
            rendered="#{cc.attrs.showActions and loginUser.allowedToViewActions}">
            <f:facet name="header">#{i18n['actions']}</f:facet>
            <h:commandLink id="actions">
              <span>#{i18n['actions']}</span>
              <f:attribute name="communityMember" value="#{member}" />
            </h:commandLink>
          </h:column>
        </h:dataTable> 
        <h:outputText styleClass="warning" rendered="#{empty cc.attrs.memberList}"
          value="#{i18n['no-records-found']}." />
      </div>
    </composite:implementation>
    </html> 

这是输出:

Dec 6, 2012 11:11:08 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 3328 ms
11:23:01,616  INFO MemberController:43 - constructing MemberController
11:23:07,446 DEBUG MemberController:139 - getSortActionListener called
11:23:07,456 DEBUG MemberController:180 - constructing comparator map
11:23:07,466 DEBUG MemberController:213 - constructing SortActionListener
11:23:07,476 DEBUG MemberController:227 - Sorting by lastName Ascending (MemberController$SortActionListener@779d9c0d)
11:23:07,476 DEBUG MemberController:139 - getSortActionListener called
11:23:07,476 DEBUG MemberController:227 - Sorting by lastName Descending (MemberController$SortActionListener@779d9c0d)
11:23:12,116 DEBUG MemberController:127 - getActionsActionListener called
11:23:12,126 DEBUG MemberController:132 - action for homer@simpsons.tv

从输出来看,第一个 actionListener 调用了两次,但第二个按预期只调用了一次。

这是使用 jsf 2.1.13 在 tomecat 6.0.36 下运行的。如果我使用 myfaces 而不是 jsf,就没有这个问题。

4

0 回答 0