我已经在即将出版的PrimeFaces Cookbook 2版中写了一篇关于食谱的博客。 在这篇文章中,我想发表第二篇关于一个名为Dialog Framework
的小型框架的文章。 我个人喜欢它,因为我记得我为使用Struts框架付出同样的努力而付出的代价。 当您想将外部页面加载到弹出窗口中并向该页面提交一些数据时,您必须使用隐藏表单调用window.open
,将传递的值设置为隐藏字段,通过JavaScript将表单提交给外部页面,然后等到该页面已准备好在window.onload
或document.ready
。 很多繁琐的工作。 PrimeFaces可以为您完成这项工作,此外, p:dialog
还提供了漂亮的用户界面来替代弹出窗口。
PrimeFaces对话框的常规用法是使用p:dialog
的声明方法。 除了这种声明式方法之外,还有一种编程方法。 编程方法基于编程API,其中在运行时创建和销毁对话框。 它称为Dialog Framework
。 对话框框架用于在动态生成的对话框中打开外部页面。 用法很简单, RequestContext
提供两个方法: openDialog
和closeDialog
允许打开和关闭动态对话框。 此外,对话框架使将数据从对话中显示的页面传回至调用者页面成为可能。
在本食谱中,我们将演示Dialog Framework中可用的所有功能。 我们将以编程方式打开一个带有选项的对话框,并将参数传递给该对话框中显示的页面。 我们还将满足在源(调用方)页面和对话框之间进行通信的可能性。
做好准备
Dialog Framework在faces-config.xml
需要以下配置:
<application><action-listener>org.primefaces.application.DialogActionListener</action-listener><navigation-handler>org.primefaces.application.DialogNavigationHandler</navigation-handler><view-handler>org.primefaces.application.DialogViewHandler</view-handler>
</application>
怎么做…
我们将开发一个带有单选按钮的页面,以选择一本可用的PrimeFaces图书进行评级。 单击按钮“ Rate the selected book
后,评分本身将在对话框中发生。
屏幕快照的XHTML代码段在下面列出。
<p:messages id="messages" showSummary="true" showDetail="false"/><p:selectOneRadio id="books" layout="pageDirection" value="#{dialogFrameworkBean.bookName}"><f:selectItem itemLabel="PrimeFaces Cookbook" itemValue="PrimeFaces Cookbook"/><f:selectItem itemLabel="PrimeFaces Starter" itemValue="PrimeFaces Starter"/><f:selectItem itemLabel="PrimeFaces Beginner's Guide" itemValue="PrimeFaces Beginner's Guide"/><f:selectItem itemLabel="PrimeFaces Blueprints" itemValue="PrimeFaces Blueprints"/>
</p:selectOneRadio><p:commandButton value="Rate the selected book"process="@this books"actionListener="#{dialogFrameworkBean.showRatingDialog}"style="margin-top: 15px"><p:ajax event="dialogReturn" update="messages" listener="#{dialogFrameworkBean.onDialogReturn}"/>
</p:commandButton>
对话框中的页面是整页bookRating.xhtml
其中包含Rating组件p:rating
。 它还显示选择进行评级的书的名称。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"xmlns:f="http://xmlns.jcp.org/jsf/core"xmlns:h="http://xmlns.jcp.org/jsf/html"xmlns:p="http://primefaces.org/ui">
<f:view contentType="text/html" locale="en"><f:metadata><f:viewParam name="bookName" value="#{bookRatingBean.bookName}"/></f:metadata><h:head><title>Rate the book!</title></h:head><h:body><h:form>What is your rating for the book <strong>#{bookRatingBean.bookName}</strong>?<p/><p:rating id="rating"><p:ajax event="rate" listener="#{bookRatingBean.onrate}"/><p:ajax event="cancel" listener="#{bookRatingBean.oncancel}"/></p:rating></h:form></h:body>
</f:view>
</html>
下一个屏幕截图演示了对话框的外观。
单击等级星级或取消符号将关闭对话框。 源(呼叫者)页面显示一条消息,其中所选的评级值在0到5之间。
最有趣的部分是bean中的逻辑。 豆DialogFrameworkBean
通过调用方法打开的对话框中的等级页面openDialog()
与结果,选项和POST参数上RequestContext
实例。 此外,bean定义了一个AJAX侦听器onDialogReturn()
,当对话框关闭后从对话框返回数据(选定的评级)时,将调用该侦听onDialogReturn()
。
@Named
@ViewScoped
public class DialogFrameworkBean implements Serializable {private String bookName;public void showRatingDialog() {Map<String, Object> options = new HashMap<String, Object>();options.put("modal", true);options.put("draggable", false);options.put("resizable", false);options.put("contentWidth", 500);options.put("contentHeight", 100);options.put("includeViewParams", true);Map<String, List<String>> params = new HashMap<String, List<String>>();List<String> values = new ArrayList<String>();values.add(bookName);params.put("bookName", values);RequestContext.getCurrentInstance().openDialog("/views/chapter11/bookRating", options, params);}public void onDialogReturn(SelectEvent event) {Object rating = event.getObject();FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "You rated the book with " + rating, null);FacesContext.getCurrentInstance().addMessage(null, message);}// getters / setters...
}
Bean BookRatingBean
为Rating component
定义了两个侦听器。 当用户分别单击星号和取消符号时,将调用它们。 我们呼吁有closeDialog()
上RequestContext
实例来触发对话框关闭和额定电流值传递给听众提到onDialogReturn()
@Named
@RequestScoped
public class BookRatingBean {private String bookName;public void onrate(RateEvent rateEvent) {RequestContext.getCurrentInstance().closeDialog(rateEvent.getRating());}public void oncancel() {RequestContext.getCurrentInstance().closeDialog(0);}// getters / setters...
}
怎么运行的…
RequestContext
提供了两个同名openDialog
方法,可在运行时动态打开对话框。 第一个只有一个参数–用于解决导航案例的逻辑结果。 第二个参数包含三个参数-结果,对话框的配置选项和发送到对话框中显示的视图的参数。 在示例中,我们使用了第二个变体。 选项作为键值对放入Map
中。 参数也放入Map
。 在我们的案例中,我们输入所选书籍的名称。 之后,通过f:viewParam
在对话框页面bookRating.xhtml
接收该名称。 f:viewParam
将传输的参数设置到BookRatingBean
,以便在Rating
组件上方的标题中可用。
提示:请参阅《 PrimeFaces用户指南》以查看支持的对话框的配置选项的完整列表。
让我们经历一下请求-响应生命周期。 一旦收到由命令按钮引起的请求响应,便会创建一个对话框,其中包含iframe
。 iframe
的URL指向整页,在本例中为bookRating.xhtml
。 该页面将向下流并显示在对话框中。 如您所见,总是有两个请求:第一个初始POST和第二个GET由iframe发送。 请注意,对话框框架仅适用于初始AJAX请求。 非AJAX请求将被忽略。 另请注意,对话框的标题取自HTML title
元素。
正如我们上面已经提到,这个对话框可以通过编程关闭invoking
该方法closeDialog
上RequestContext
实例。 在调用者页面上,触发对话框的按钮需要具有一个dialogReturn
事件的AJAX侦听器,以便能够从对话框接收任何数据。 数据作为参数传递给方法closeDialog(Object data)
。 在示例中,我们传递了一个正整数值rateEvent.getRating()
或0
。
翻译自: https://www.javacodegeeks.com/2015/01/primefaces-opening-external-pages-in-dynamically-generated-dialog.html