谁能澄清一下我们如何在一般情况下或在现实世界中的例子中使用这个片段?
<f:metadata>
<f:viewParam id="id" value="#{bean.id}" />
<f:viewAction action="#{bean.init}" />
</f:metadata>
进程 GET 参数
<f:viewParam>
管理 GET 参数的设置、转换和验证。这就像<h:inputText>
,但对于GET参数。
以下示例
<f:metadata>
<f:viewParam name="id" value="#{bean.id}" />
</f:metadata>
基本上执行以下操作:
- 按名称
id
获取请求参数值。 - 如有必要,转换并验证它(您可以使用
required
、validator
和converter
属性,并像<h:inputText>
一样在其中嵌套<f:converter>
和<f:validator>
( - 如果转换和验证成功,则将其设置为由
#{bean.id}
值表示的 Bean 属性,或者如果不存在value
属性,则将其设置为名称id
的请求属性,以便视图中的#{id}
可用。
因此,当您以foo.xhtml?id=10
方式打开页面时,10
以这种方式在 Bean 中设置参数值,就在呈现视图之前。
至于验证,以下示例将参数设置为 required="true"
,并且只允许 10 到 20 之间的值。任何验证失败都将导致显示一条消息。
<f:metadata>
<f:viewParam id="id" name="id" value="#{bean.id}" required="true">
<f:validateLongRange minimum="10" maximum="20" />
</f:viewParam>
</f:metadata>
<h:message for="id" />
<小时 />对 GET 参数执行业务操作
您可以使用<f:viewAction>
执行此操作。
<f:metadata>
<f:viewParam id="id" name="id" value="#{bean.id}" required="true">
<f:validateLongRange minimum="10" maximum="20" />
</f:viewParam>
<f:viewAction action="#{bean.onload}" />
</f:metadata>
<h:message for="id" />
跟
public void onload() {
// ...
}
然而,自 JSF 2.2 以来,该<f:viewAction>
是新的(自 JSF 2.0 以来,<f:viewParam>
已经存在(。如果无法升级,则最好的办法是改用<f:event>
。
<f:event type="preRenderView" listener="#{bean.onload}" />
但是,每个请求都会调用它。您需要显式检查请求是否不是回发:
public void onload() {
if (!FacesContext.getCurrentInstance().isPostback()) {
// ...
}
}
当您还想跳过"转换/验证失败"的情况时,请执行以下操作:
public void onload() {
FacesContext facesContext = FacesContext.getCurrentInstance();
if (!facesContext.isPostback() && !facesContext.isValidationFailed()) {
// ...
}
}
以这种方式使用<f:event>
本质上是一种解决方法/黑客,这正是在 JSF 2.2 中引入<f:viewAction>
的原因。
将视图参数传递到下一个视图
您可以通过将属性设置为 true
或添加请求参数includeViewParams
来"传递"导航链接中的视图参数includeViewParams=true
。
<h:link outcome="next" includeViewParams="true">
<!-- Or -->
<h:link outcome="next?includeViewParams=true">
使用上面的<f:metadata>
示例生成基本上是以下链接
<a href="next.xhtml?id=10">
使用原始参数值。
这种方法只要求next.xhtml
对同一参数也有一个<f:viewParam>
,否则它不会被传递。
在 JSF 中使用 GET 表单
该<f:viewParam>
也可以与"纯HTML"GET表单结合使用。
<f:metadata>
<f:viewParam id="query" name="query" value="#{bean.query}" />
<f:viewAction action="#{bean.search}" />
</f:metadata>
...
<form>
<label for="query">Query</label>
<input type="text" name="query" value="#{empty bean.query ? param.query : bean.query}" />
<input type="submit" value="Search" />
<h:message for="query" />
</form>
...
<h:dataTable value="#{bean.results}" var="result" rendered="#{not empty bean.results}">
...
</h:dataTable>
基本上这个@RequestScoped
豆:
private String query;
private List<Result> results;
public void search() {
results = service.search(query);
}
请注意,<h:message>
是针对<f:viewParam>
的,而不是纯HTML <input type="text">
!另请注意,当#{bean.query}
输入值为空时,输入值会显示#{param.query}
,因为当出现验证或转换错误时,提交的值根本不会显示。请注意,此构造对于 JSF 输入组件无效(它已经在"幕后"执行此操作(。
另请参阅:
- ViewParam vs @ManagedProperty(value = "#{param.id}"(
- JSF 2.0 中的通信 - 处理 GET 请求参数
将参数从视图发送到另一个视图,从发送方视图发送到接收方视图使用 viewParam 和 includeViewParams=true
在发件人中
- 声明要发送的参数。我们可以发送字符串,对象,...
发件人.xhtml
<f:metadata>
<f:viewParam name="ID" value="#{senderMB._strID}" />
</f:metadata>
- 我们将发送参数 ID,它将包含在
“includeViewParams=true”
中作为回报 单击按钮事件的字符串单击按钮触发发件人MB.clickBtnDetail(dto( 与dto从senderMB._arrData
发件人.xhtml
<p:dataTable rowIndexVar="index" id="dataTale"value="#{senderMB._arrData}" var="dto">
<p:commandButton action="#{senderMB.clickBtnDetail(dto)}" value="見る"
ajax="false"/>
</p:dataTable>
在senderMB.clickBtnDetail(dto(中,我们用从按钮事件(dto(获得的参数分配_strID,这里Sender_DTO并分配给senderMB._strID
Sender_MB.java
public String clickBtnDetail(sender_DTO sender_dto) {
this._strID = sender_dto.getStrID();
return "Receiver?faces-redirect=true&includeViewParams=true";
}
单击后的链接将变为http://localhost:8080/my_project/view/Receiver.xhtml?*ID=12345*
在接收中
- 获取视图参数接收器.xhtml在接收器中,我们声明 f:viewParam 以从 get 请求(接收(获取参数,接收器的参数名称必须与发送方(页面(相同
接收器.xhtml
<f:metadata><f:viewParam name="ID" value="#{receiver_MB._strID}"/></f:metadata>
它将从发件人视图获取参数 ID 并分配给 receiver_MB._strID
- 使用视图参数在 Receiver 中,我们希望在页面呈现之前在 sql 查询中使用此参数,以便我们使用 preRenderView 事件。我们不打算使用构造函数,因为在收到 viewParam 之前将调用构造函数这样我们添加
接收器.xhtml
<f:event listener="#{receiver_MB.preRenderView}" type="preRenderView" />
到 f:元数据标记
接收器.xhtml
<f:metadata>
<f:viewParam name="ID" value="#{receiver_MB._strID}" />
<f:event listener="#{receiver_MB.preRenderView}"
type="preRenderView" />
</f:metadata>
现在我们想在我们的读取数据库方法中使用此参数,它可以使用
Receiver_MB.java
public void preRenderView(ComponentSystemEvent event) throws Exception {
if (FacesContext.getCurrentInstance().isPostback()) {
return;
}
readFromDatabase();
}
private void readFromDatabase() {
//use _strID to read and set property
}