简体   繁体   English

什么可以<f:metadata> ,<f:viewParam> 和<f:viewAction>用于?

[英]What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?

Can anyone clarify how we can use in general, or a in real world example, this snippet?任何人都可以澄清我们一般如何使用这个片段,或者在现实世界中的例子吗?

<f:metadata>
    <f:viewParam id="id" value="#{bean.id}" />
    <f:viewAction action="#{bean.init}" />
</f:metadata>

Process GET parameters处理GET参数

The <f:viewParam> manages the setting, conversion and validation of GET parameters. <f:viewParam>管理 GET 参数的设置、转换和验证。 It's like the <h:inputText> , but then for GET parameters.它就像<h:inputText> ,但是对于 GET 参数。

The following example下面的例子

<f:metadata>
    <f:viewParam name="id" value="#{bean.id}" />
</f:metadata>

does basically the following:基本上执行以下操作:

  • Get the request parameter value by name id .通过名称id获取请求参数值。
  • Convert and validate it if necessary (you can use required , validator and converter attributes and nest a <f:converter> and <f:validator> in it like as with <h:inputText> )如有必要,转换并验证它(您可以使用requiredvalidatorconverter属性并在其中嵌套<f:converter><f:validator> ,就像<h:inputText>
  • If conversion and validation succeeds, then set it as a bean property represented by #{bean.id} value, or if the value attribute is absent, then set it as request attribtue on name id so that it's available by #{id} in the view.如果转换和验证成功,则将其设置为由#{bean.id}值表示的 bean 属性,或者如果value属性不存在,则将其设置为 name id上的请求属性,以便它在#{id}中可用风景。

So when you open the page as foo.xhtml?id=10 then the parameter value 10 get set in the bean this way, right before the view is rendered.因此,当您以foo.xhtml?id=10打开页面时,参数值10以这种方式在 bean 中设置,就在视图呈现之前。

As to validation, the following example sets the param to required="true" and allows only values between 10 and 20. Any validation failure will result in a message being displayed.至于验证,以下示例将参数设置为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" />

Performing business action on GET parameters对 GET 参数执行业务操作

You can use the <f:viewAction> for this.您可以<f:viewAction>使用<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" />

with

public void onload() {
    // ...
}

The <f:viewAction> is however new since JSF 2.2 (the <f:viewParam> already exists since JSF 2.0).然而<f:viewAction>自 JSF 2.2 以来是新的( <f:viewParam>自 JSF 2.0 以来已经存在)。 If you can't upgrade, then your best bet is using <f:event> instead.如果您无法升级,那么最好的办法是使用<f:event>代替。

<f:event type="preRenderView" listener="#{bean.onload}" />

This is however invoked on every request.然而,这在每个请求上都会被调用。 You need to explicitly check if the request isn't a postback:您需要明确检查请求是否不是回发:

public void onload() {
    if (!FacesContext.getCurrentInstance().isPostback()) {
        // ...
    }
}

When you would like to skip "Conversion/Validation failed" cases as well, then do as follows:如果您还想跳过“转换/验证失败”的情况,请执行以下操作:

public void onload() {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    if (!facesContext.isPostback() && !facesContext.isValidationFailed()) {
        // ...
    }
}

Using <f:event> this way is in essence a workaround/hack, that's exactly why the <f:viewAction> was introduced in JSF 2.2.以这种方式使用<f:event>本质上是一种解决方法/hack,这正是在 JSF 2.2 中引入<f:viewAction>原因。


Pass view parameters to next view将视图参数传递给下一个视图

You can "pass-through" the view parameters in navigation links by setting includeViewParams attribute to true or by adding includeViewParams=true request parameter.您可以通过将includeViewParams属性设置为true或添加includeViewParams=true请求参数来“传递”导航链接中的视图参数。

<h:link outcome="next" includeViewParams="true">
<!-- Or -->
<h:link outcome="next?includeViewParams=true">

which generates with the above <f:metadata> example basically the following link使用上面的<f:metadata>示例基本上生成以下链接

<a href="next.xhtml?id=10">

with the original parameter value.与原始参数值。

This approach only requires that next.xhtml has also a <f:viewParam> on the very same parameter, otherwise it won't be passed through.这种方法只需要next.xhtml在同一个参数上有一个<f:viewParam> ,否则它不会被传递。


Use GET forms in JSF在 JSF 中使用 GET 表单

The <f:viewParam> can also be used in combination with "plain HTML" GET forms. <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>

With basically this @RequestScoped bean:基本上这个@RequestScoped bean:

private String query;
private List<Result> results;

public void search() {
    results = service.search(query);
}

Note that the <h:message> is for the <f:viewParam> , not the plain HTML <input type="text"> !请注意, <h:message>用于<f:viewParam> ,而不是纯 HTML <input type="text"> Also note that the input value displays #{param.query} when #{bean.query} is empty, because the submitted value would otherwise not show up at all when there's a validation or conversion error.另请注意,当#{bean.query}为空时,输入值会显示#{param.query} ,因为否则当出现验证或转换错误时,提交的值根本不会显示。 Please note that this construct is invalid for JSF input components (it is doing that "under the covers" already).请注意,此构造对于 JSF 输入组件无效(它已经在“幕后”这样做了)。


See also:也可以看看:

Send params from View to an other View, from Sender View to Receiver View use viewParam and includeViewParams=true将参数从 View 发送到另一个 View,从 Sender View 到 Receiver View 使用 viewParam 和 includeViewParams=true

In Sender在发件人中

  1. Declare params to be sent.声明要发送的参数。 We can send String, Object,…我们可以发送字符串、对象、...

Sender.xhtml发件人.xhtml

<f:metadata>
      <f:viewParam name="ID" value="#{senderMB._strID}" />
</f:metadata>
  1. We're going send param ID, it will be included with “includeViewParams=true” in return String of click button event Click button fire senderMB.clickBtnDetail(dto) with dto from senderMB._arrData我们将发送参数 ID,它将包含在“includeViewParams=true”中,作为点击按钮事件的返回字符串 点击按钮使用来自 senderMB._arrData 的 dto 触发 senderMB.clickBtnDetail(dto)

Sender.xhtml发件人.xhtml

<p:dataTable rowIndexVar="index" id="dataTale"value="#{senderMB._arrData}" var="dto">
      <p:commandButton action="#{senderMB.clickBtnDetail(dto)}" value="見る" 
      ajax="false"/>
</p:dataTable>

In senderMB.clickBtnDetail(dto) we assign _strID with argument we got from button event (dto), here this is Sender_DTO and assign to senderMB._strID在 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";
    }

The link when clicked will become http://localhost:8080/my_project/view/Receiver.xhtml?*ID=12345*点击后的链接会变成http://localhost:8080/my_project/view/Receiver.xhtml?*ID=12345*

In Recever在接收

  1. Get viewParam Receiver.xhtml In Receiver we declare f:viewParam to get param from get request (receive), the name of param of receiver must be the same with sender (page)获取viewParam Receiver.xhtml 在Receiver中我们声明f:viewParam从get请求(receive)中获取param,receiver的param名称必须与sender(page)一致

Receiver.xhtml接收器.xhtml

<f:metadata><f:viewParam name="ID" value="#{receiver_MB._strID}"/></f:metadata>

It will get param ID from sender View and assign to receiver_MB._strID它将从发送者视图中获取参数 ID 并分配给接收者_MB._strID

  1. Use viewParam In Receiver, we want to use this param in sql query before the page render, so that we use preRenderView event.使用 viewParam 在 Receiver 中,我们希望在页面渲染之前的 sql 查询中使用此参数,以便我们使用 preRenderView 事件。 We are not going to use constructor because constructor will be invoked before viewParam is received So that we add我们不会使用构造函数,因为构造函数会在收到 viewParam 之前被调用 所以我们添加

Receiver.xhtml接收器.xhtml

<f:event listener="#{receiver_MB.preRenderView}" type="preRenderView" />

into f:metadata tag进入 f:metadata 标签

Receiver.xhtml接收器.xhtml

<f:metadata>
<f:viewParam name="ID" value="#{receiver_MB._strID}" />
<f:event listener="#{receiver_MB.preRenderView}"
            type="preRenderView" />
</f:metadata>

Now we want to use this param in our read database method, it is available to use现在我们想在我们的读取数据库方法中使用这个参数,它可以使用

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   
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM