Passing parameters to a view scoped bean in JSF

2019-01-09 01:48发布

问题:

Lets imagine I have two pages in my JSF 2 application: the first page displays a table of objects (cars or whatever) and another page is able to display the details of one specific object. The table page is in request scope because the objects should be reloaded each time the user requests it. The detail page is in view scope. So when I click on an object inside the table, this object should be displayed in the details page. With a redirect I am able to go to the details page but the detail page is empty, because a new vew was generated. Ok, I could change the scope to session but this would lead to other problems, so I would like to have the details page in view scope. Is there a way of passing an argument to a newly generted view scope bean?

UPDATE 1

Here is the code snippet with the first try of using view parameters. As commented this does not work. The value gets passed as request parameter but in the target page the value is null.

Table page:

<h:button value="Go to details" outcome="targetPage">
     <f:param name="carId" value="This is a test" />
</h:button>

Details page:

<f:metadata>
    <f:viewParam name="carId" value="#{bean.id}" />
    <f:event type="preRenderView" listener="#{bean.loadData}"/>
</f:metadata>

Bean of details page:

private String id;

public String getId() {
    return id;
}

public void setId( String id ) {
    this.id = id;
}

public void loadData() {
    System.out.println( "Id: " + id );
}

UPDATE 2

I have found my mistake. The metadata part was inside a template file. When I put the tag to the main file for the details page it works. Thank you very much.

回答1:

Using view parameters is the most proper way for your case. You don't really need to perform a REDIRECT, but a plain GET request:

<h:button value="Go to details" outcome="carDetails">
    <f:param name="carId" value="#{currentCar.id}" />
</h:button>

This will head you to this: carDetails.xhtml?carId=1

After that, in your carDetails.xhtml page, catch the view param and load the info for that car:

<f:metadata>
    <f:viewParam name="carId" value="#{carDetailBean.carId}" />
    <f:event type="preRenderView" listener="#{carDetailBean.loadData}"/>
</f:metadata>

Where CarDetailBean#loadData just loads the info for your car to display with the given id, already set into the bean.

See also:

  • Difference between h:button and h:commandButton
  • What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?