我正在尝试实现一个p:对话框。其中有一个选择列表。在选定项目的基础上,我需要更新对话框上的模板。这工作正常。但是如果我在动态渲染的模板中有<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
twitter.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,它是templates目录下任何模板的一部分。我使用的是JSF 2.1.7和Primefaces 3.3。
答案 0 :(得分:2)
罪魁祸首在这里:
<ui:include src="#{contactBean.resolveTemplate(requestScope.selectedMedia)}"/>
这不仅在显示表单的初始HTTP请求期间进行评估,而且还在后续HTTP请求期间评估,其中要处理表单提交。
selectedMedia
似乎是一个请求范围的变量,在初始请求结束时会丢失。因此,在处理表单提交的后续HTTP请求中,它将评估为null
,并且在构建视图期间根本不会包含任何模板。这样,JSF将无法运行命令按钮组件的decode()
,因此它的操作永远不会被确定并排队。
您需要确保在后续HTTP请求中保留selectedMedia
变量。其中一种方法是通过命令按钮内的<f:param>
或表单内的<input type="hidden">
将其作为请求参数传递给后续请求。
答案 1 :(得分:0)
bean中actionListener的方法应该有ActionEvent
参数。见tutorial
答案 2 :(得分:0)
删除子模板中使用的<h:form>
。在父模板中仅保留一个<h:form>
,并使用<ui:include>