f:param
适用于h:link
,但不适用于p:commandLink
或h:commandLink
。
例如,我有两个页面test_first.xhtml
和test_second.xhtml
,以及一个支持java bean TestBean.java
。
我开始运行test_first.xhtml
。
如果我点击link1
h:link
,则该页面将重定向到test_second.xhtml
。在f:param
的帮助下,浏览器的地址栏将显示.../test_second.xhtml?id=1
。在该页面上,testBean.userId
被打印出来。
如果我点击link2
或link3
,该网页会重定向到test_second.xhtml
。但是,地址栏只显示.../test_second.xhtml
,没有?id=#
!并且testBean.userId
不会打印在该页面上。
如何让commandLink
与f:param
合作?有时我希望链接不会重定向到另一个页面,而是根据数据调用bean的某些方法。
test_first.xhtml:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head/>
<h:body>
<h:form>
<h:link value="link1" outcome="test_second" >
<f:param name="id" value="1"/>
</h:link>
<br/><br/>
<h:commandLink value="link2" action="test_second?faces-redirect=true" >
<f:param name="id" value="2" />
</h:commandLink>
<br/><br/>
<p:commandLink value="link3" action="test_second?faces-redirect=true">
<f:param name="id" value="3" />
</p:commandLink>
<br/><br/>
</h:form>
</h:body>
</html>
test_second.xhtml:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<f:metadata>
<f:viewParam name="id" value="#{testBean.userId}" />
</f:metadata>
<h:head/>
<h:body>
<h:form>
This is the second page.
<h:outputText value="Selected id is #{testBean.userId}" />
<h:commandButton value="Print page id" action="#{testBean.print()}" />
</h:form>
</h:body>
</html>
TestBean.java
@ManagedBean
@SessionScoped
public class TestBean implements Serializable{
private Integer userId;
public void print() {
System.out.println(userId);
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
}
答案 0 :(得分:7)
你误解了这两个标签的含义,即<h:link>
和<h:commandLink>
,因此,你也误解了附加在两者之一的<f:param>
的含义。无论如何,在提出问题以获得更多见解之前,始终阅读文档是值得的。
<h:link>
呈现HTML“a”锚元素。组件的值呈现为锚文本,组件的结果用于确定在“href”属性中呈现的目标URL。 任何子UIParameter
组件都会附加到String中,以便在呈现之前作为查询参数的“href”属性的值输出...
<h:commandLink>
呈现一个HTML“a”锚元素,当单击时表现为表单提交按钮* ...如果禁用的属性不存在,或者其值为false。它将“#”呈现为“href”属性的值,将组件的当前值呈现为链接文本(如果已指定),并且*将与功能上等效于以下内容的JavaScript呈现为“onclick”属性的值:document.forms['CLIENT_ID']['hiddenFieldName'].value='CLIENT_ID'; document.forms['CLIENT_ID']['PARAM1_NAME'].value='PARAM1_VALUE'; document.forms['CLIENT_ID']['PARAM2_NAME'].value='PARAM2_VALUE'; return false; document.forms['CLIENT_ID'].submit()"
其中
hiddenFieldName
如上所述,CLIENT_ID是UICommand组件的clientId, PARAM _NAME和PARAM _VALUE分别是任何嵌套UIParameter的名称和值儿童
换句话说,在<h:link>
标记内,嵌套<f:param>
最终将作为生成的网址的查询参数,而在<h:commandLink>
标记内,嵌套<f:param>
将最终为具有给定值的请求参数。
虽然第一个是明确的,但第二个值得更好地阐述。要了解它的作用,请考虑如果我们从详细信息中抽象出来<h:commandLink>
发送POST请求并将所有嵌套的<f:param>
标记作为请求参数附加。但是由你来决定如何处理它们,因为导航完全在你手中。
所以,第一个选项是设置一个硬编码的action
属性,哪个用例可疑,就像action="second-page"
一样,你没有' t传递任何查询参数。将要做的是POST到相同的视图并转发到第二个视图而不进行任何操作。相当愚蠢的行动。
第二个选项是指定一个操作方法,例如action="#{bean.action}"
。在这种情况下您必须在提供的操作方法中处理导航,即从回发方法返回null
/ void
,或者将导航案例结果作为字符串返回到转发到指定的视图。至于您使用<f:param>
传递的请求参数,它们将在请求范围的bean上使用标准JSF意味着,如@ManagedProperty("#{param.name}")
,或者通过调用ExternalContext#getRequestParameterMap()
在任何作用域中,例如,在动作方法中,如String param = externalContext.getRequestParameterMap().get("name")
中所示。现在,您可以使用参数in action方法随意使用自己喜欢的方式,只需遵守一系列适用于URL的规则。
还有两件事值得一提。请记住,通过调用命令链接传递的请求参数将仅在同一请求中可用,因为您可能希望它能够在基本上触发另一个请求的faces-redirect=true
中生存。另一个选项是指定includeviewparams=true
来传递当前视图的参数,如果需要的话,如另一个答案所述。
答案 1 :(得分:2)
您可以通过直接在action属性中将参数与&
连接来实现:
<p:commandLink value="link3" action="test_second?faces-redirect=true&id=3"/>
更新1
您也可以考虑添加&includeViewParams=true
。这样,您的目标导航视图参数将自动包含在内。