What can , and be used for?

前端 未结 2 1107
星月不相逢
星月不相逢 2020-11-21 05:17

Can anyone clarify how we can use in general, or a in real world example, this snippet?


    

        
相关标签:
2条回答
  • 2020-11-21 05:17

    Process GET parameters

    The <f:viewParam> manages the setting, conversion and validation of GET parameters. It's like the <h:inputText>, but then for GET parameters.

    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.
    • 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>)
    • 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.

    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.

    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.

    <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

    You can use the <f:viewAction> for this.

    <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). If you can't upgrade, then your best bet is using <f:event> instead.

    <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.


    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.

    <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

    <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.


    Use GET forms in JSF

    The <f:viewParam> can also be used in combination with "plain HTML" GET forms.

    <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:

    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">! 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. Please note that this construct is invalid for JSF input components (it is doing that "under the covers" already).


    See also:

    • ViewParam vs @ManagedProperty(value = "#{param.id}")
    • Communication in JSF 2.0 - Processing GET request parameters
    0 讨论(0)
  • 2020-11-21 05:36

    Send params from View to an other View, from Sender View to Receiver View use viewParam and includeViewParams=true

    In Sender

    1. Declare params to be sent. We can send String, Object,…

    Sender.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

    Sender.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

    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*

    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)

    Receiver.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

    1. Use viewParam In Receiver, we want to use this param in sql query before the page render, so that we use preRenderView event. We are not going to use constructor because constructor will be invoked before viewParam is received So that we add

    Receiver.xhtml

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

    into f:metadata tag

    Receiver.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   
    }
    
    0 讨论(0)
提交回复
热议问题