任何人都可以澄清我们如何在一般情况下使用,或者在现实世界的例子中使用这个片段吗?
<f:metadata>
<f:viewParam id="id" value="#{bean.id}" />
<f:viewAction action="#{bean.init}" />
</f:metadata>
答案 0 :(得分:280)
<f:viewParam>
管理GET参数的设置,转换和验证。它就像<h:inputText>
,但接着是GET参数。
以下示例
<f:metadata>
<f:viewParam name="id" value="#{bean.id}" />
</f:metadata>
基本上做了以下几点:
id
获取请求参数值。required
,validator
和converter
属性并在其中嵌套<f:converter>
和<f:validator>
,就像使用<h:inputText>
)#{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" />
您可以使用<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() {
// ...
}
然而<f:viewAction>
是新的,因为JSF 2.2(<f:viewParam>
自JSF 2.0以来已经存在)。如果您无法升级,那么您最好的选择是使用<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>
的原因。
通过将includeViewParams
属性设置为true
或添加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
在同一参数上具有也 a <f:viewParam>
,否则将无法通过。
<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
bean:
private String query;
private List<Result> results;
public void search() {
results = service.search(query);
}
请注意,<h:message>
适用于<f:viewParam>
,而不是纯HTML <input type="text">
!另请注意,当#{param.query}
为空时,输入值会显示#{bean.query}
,因为当出现验证或转换错误时,提交的值根本不会显示。请注意,这个结构对于JSF输入组件是无效的(它已经“在幕后”了)。
答案 1 :(得分:1)
使用viewParam和includeViewParams = true
将参数从View发送到另一个View,从Sender View发送到Receiver View。在发件人中
Sender.xhtml
<f:metadata>
<f:viewParam name="ID" value="#{senderMB._strID}" />
</f:metadata>
“includeViewParams=true”
中,以作为点击按钮事件的返回字符串
单击按钮使用senderMB._arrData中的dto触发senderMB.clickBtnDetail(dto)Sender.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)中,我们将_strID分配给我们从按钮事件(dto)获得的参数,这里是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*
在接收中
Receiver.xhtml
<f:metadata><f:viewParam name="ID" value="#{receiver_MB._strID}"/></f:metadata>
它将从发送者视图获取参数ID,并将其分配给receive_MB._strID
Receiver.xhtml
<f:event listener="#{receiver_MB.preRenderView}" type="preRenderView" />
插入f:metadata标签
Receiver.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
}