我在一个数据表中有一个Primefaces命令链接,当单击时,调用Managed Bean (ViewScoped)中的一个方法,该方法重定向到另一个页面。在这个命令链接中,我调用填充一个将在命运页面中使用的属性。但是,在此命运页中,该属性为空。
导航规则:<navigation-rule>
<display-name>pages/proprietario/index.xhtml</display-name>
<!-- Origin page -->
<from-view-id>/pages/proprietario/index.xhtml</from-view-id>
<navigation-case>
<!-- Managed bean method -->
<from-action>#{proprietarioMB.doPrepareCadastro}</from-action>
<from-outcome>cadastro</from-outcome>
<!-- Destiny page -->
<to-view-id>/pages/proprietario/cadastro.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
源页中的命令链接
<p:dataTable id="tblResultados"
value="#{proprietarioMB.proprietarios}" var="proprietario">
<p:commandLink id="lnkEditar" value="#{msg['titulo.visualizar']}"
title="#{msg['titulo.visualizar']}"
action="#{proprietarioMB.doPrepareCadastro}">
<f:setPropertyActionListener
target="#{proprietarioMB.proprietario}" value="#{proprietario}" />
</p:commandLink>
</p:dataTable>
受管Bean
@ManagedBean
@ViewScoped
public class ProprietarioMB extends BaseMB {
private List<ProprietarioORM> proprietarios;
private ProprietarioORM proprietario;
public String doPrepareCadastro() {
System.out.println("ProprietarioMB.doOpenDialogoProprietario(): "
+ this.proprietario);
return "cadastro";
}
}
命运页
<?xml version="1.0" encoding="UTF-8"?>
<!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:p="http://primefaces.org/ui">
<ui:composition template="/template/template.xhtml">
<ui:define name="header">#{msg['proprietario.titulo.cadastro']}</ui:define>
<ui:define name="content">
<h:form id="formPrincipal">
<br />
<h:outputText value="#{proprietarioMB.proprietario}" />
</h:form>
</ui:define>
</ui:composition>
</html>
给我的另一个选择是在commandLink中使用,并在destiny页面中使用。或多或少如ViewParam vs @ManagedProperty(value = "#{param.id}")所示。这样,代码修改如下:
源页中的命令链接
<p:dataTable id="tblResultados"
value="#{proprietarioMB.proprietarios}" var="proprietario">
<h:link id="lnkEditar" value="#{msg['titulo.visualizar']}"
title="#{msg['titulo.visualizar']}" outcome="contrato" >
<f:param name="idProprietario" value="#{proprietario.id}" />
</p:commandLink>
</p:dataTable>
命运页
<?xml version="1.0" encoding="UTF-8"?>
<!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:p="http://primefaces.org/ui">
<ui:composition template="/template/template.xhtml">
<f:metadata>
<f:viewParam name="idProprietario" value="#{proprietarioMB.idProprietario}" />
</f:metadata>
<ui:define name="header">#{msg['proprietario.titulo.cadastro']}</ui:define>
<ui:define name="content">
<h:form id="formPrincipal">
<br />
<h:outputText value="#{proprietarioMB.proprietario}" />
</h:form>
</ui:define>
</ui:composition>
</html>
受管Bean
@ManagedBean
@ViewScoped
public class ProprietarioMB extends BaseMB {
private Long idProprietario;
private ProprietarioORM proprietario;
public setIdProprietario(Long id) {
this.idProprietario = id;
if(id != null) {
// load proprietario
}
}
}
我的问题是,这是否是更好的选择,或者是否有更好的选择。
谢谢,Rafael阿方索
如果你从一个视图范围的页面导航到另一个,你想传递一些参数到第二个页面,最好的方法是使用flash(不是adobe flash)。从From页面传递flash中的对象,如下所示。
public String cbCallNewPageClicked() {
table.getDataTableBinding().reset();
Flash flash = FacesContext.getCurrentInstance().
getExternalContext().getFlash();
flash.put("tableBind", table.dataTableBinding);
flash.put("tableRow", table.dtos);
flash.put("tableName", table.tableName);
flash.keep("tableBind");
flash.keep("tableRow");
flash.keep("tableName");
JavascriptContext.addJavascriptCall(FacesContext.getCurrentInstance(), "openWindow('page2.jsf')");
return null;
}
在目标bean中获取flash中传递的值,如下所示
public void setFlash(ComponentSystemEvent event){
Flash flash = FacesContext.getCurrentInstance().getExternalContext().getFlash();
DataTable newBinding = (DataTable) flash.get("tableBind");
List newTblRow = (List) flash.get("tableRow");
String tableHead = (String) flash.get("tableName");
}
在preenderview事件中调用setFlash(在facelet中放入以下行,在页面加载时调用setFlash方法)
<f:event listener="#{page2Bean.setFlash}" type="preRenderView" />
您描述的第一种方法是使用POST请求进行纯页面到页面的导航。这是特别不鼓励的。无论如何,您在代码中使用了冗余的导航规则。由于JSF 2允许您使用隐式导航,因此返回cadastro
结果就像您在操作方法中所做的那样,将把您引导到POST之后的/pages/proprietario/cadastro.xhtml
。
第二条路要好得多,其实该走的路。对于h:link
,对目标页面执行GET请求。这样可以避免在源bean中执行不必要的代码,同时还可以指定要在url中使用的视图参数,使您的导航具有书签和可重用性。
参见:
- 将参数传递给JSF中的视图作用域bean
- 什么时候应该使用h:link而不是h:commandLink?
- http://balusc.blogspot.com.es/2011/09/communication -在jsf html - 20. # ImplicitNavigation