0

我正在尝试实现 ap:dialog。里面有一个选择列表。根据所选项目,我需要更新对话框上的模板。这工作正常。但是如果我<p:commandButton>在动态呈现的模板中有一个,那么它的 actionListener 永远不会被触发。

示例:view.xhtml

<p:dialog modal="true" id="addSocialMediaAddressDialogPanel" widgetVar="addSocialMediaAddressDialog" width="500" >
<h:form id="addSocialMediaAddressForm">
    <h:messages />
    <p:selectOneMenu id="currentAddingSocialMedia" value="#{requestScope.selectedMedia}" >  
        <f:selectItems value="#{WebResource.getListByName('SOCIAL_MEDIAS')}" />
        <p:ajax update="addSocialMediaAddressContentPanel" process="@this" />
    </p:selectOneMenu>
    <p:outputPanel id="addSocialMediaAddressContentPanel">
        <ui:include src="#{contactBean.resolveTemplate(requestScope.selectedMedia)}"/>
    </p:outputPanel>    
</h:form>
</p:dialog>

我有这样的模板

templates
    |_ twitter.xhtml
    |_ facebook.xhtml
    |_ googlePlus.xhtml

推特.xhtml

<table>
    <tr>
        <td>
            <h:outputLabel  styleClass="standardText" value="Twitter Screen Name"/>
        </td>
        <td>
            <p:inputText id="twitterScreenName" value="#{requestScope.twitterScreenName}"/>
        </td>
    </tr>
    <tr>
        <td>
            <p:commandButton value="Add Account" actionListener="#{contactBean.addTwitterAccount(requestScope.twitterScreenName)}" styleClass="btn-blue" process="@form" update=":growl, :messageForm"/>
        </td>
    </tr>
</table>

这是支持豆

@Component
@Scope("session")
public class ContactBean implements Serializable {

    private static String SOCIAL_MEDIA_ACCOUNTS_TEMPLATE_PARENT_DIRECTORY = "/templates/";

    public void addTwitterAccount(String screenName){
        //this contiains the implmentation
    }

    public String resolveTemplate(String socialMedia){
        if(socialMedia.equalsIgnoreCase("Twitter")){
            return SOCIAL_MEDIA_ACCOUNTS_TEMPLATE_PARENT_DIRECTORY + "twitter.xhtml";
        }
        if(socialMedia.equalsIgnoreCase("Facebook")){
            return SOCIAL_MEDIA_ACCOUNTS_TEMPLATE_PARENT_DIRECTORY + "facebook.xhtml";
        }
        else if(socialMedia.equalsIgnoreCase("Google+")){
            return SOCIAL_MEDIA_ACCOUNTS_TEMPLATE_PARENT_DIRECTORY + "googlePlus.xhtml";
        }
        return "";
    }
}

在这种情况下,我无法触发任何 actionListener,它是模板目录下任何模板的一部分。我正在使用 JSF 2.1.7 和 Primefaces 3.3。

4

3 回答 3

2

罪魁祸首在这里:

<ui:include src="#{contactBean.resolveTemplate(requestScope.selectedMedia)}"/>

这不仅在显示表单的初始 HTTP 请求期间进行评估,而且还在随后处理表单提交的 HTTP 请求期间进行评估。

selectedMedia似乎是一个请求范围的变量,在初始请求结束时会丢失。因此,在处理表单提交的后续 HTTP 请求中,它将评估为null,并且在构建视图期间根本不会包含任何模板。这样 JSF 将无法运行decode()命令按钮组件,因此它的操作将永远不会被确定和排队。

您需要确保selectedMedia在后续 HTTP 请求中保留该变量。<f:param>其中一种方法是通过命令按钮内部或<input type="hidden">表单内部将其作为请求参数传递给后续请求。

于 2013-01-03T12:05:51.187 回答
0

bean 中的 actionListener 方法应该有ActionEvent参数。看这个教程

于 2013-01-03T10:26:08.380 回答
0

删除<h:form>子模板中使用的。在父模板中只保留一个<h:form>,并在您包含在父模板中的所有其他子模板中删除它<ui:include>

于 2018-12-25T16:48:45.593 回答