3

让我们以搜索页面和结果页面为例。如果我有一个 ViewScoped bean 来处理我的搜索页面和我的结果页面,我可以使用以下方式通过 url 传递参数:

搜索.xhtml

<p:commandButton value="Search" type="submit" action="#{searchBacker.search}" >

后备豆

@ManagedBean(name="search")
@ViewScoped
public class searchBacker extends AbstractBacking {

  private String firstName = null;
  private String lastName = null;
  private String results = null;

  public String search() {
    return "results?faces-redirect=true&amp;includeViewParams=true";
  }

  public void getResults() {
    MyDAO dao = new MyDAO();
    results = dao.getResults(firstName, lastName);
  }

  //getters and setters
}

结果.xhtml

<f:metadata>
  <f:event type="preRenderView" listener="#{searchBacker.getResults}" />
  <f:viewParam name="firstName" value="#{searchBacker.firstName}"/>
  <f:viewParam name="lastName" value="#{searchBacker.lastName}"/>
</f:metadata>

现在假设我有两个托管 bean - 一个用于搜索页面,一个用于结果页面。

查询字符串是否仍会使用 2 个不同的托管 bean 在 url 中构建,或者这仅在对两个页面使用相同的托管 bean 时才有效?

更新

我的 search.xhtml 和 results.xhtml 页面上也有相同<f:viewParam>的内容,但唯一的区别是我f:viewParam value在 results.xhtml 中指向的支持者与在 search.xhtml 中的支持者不同。当我这样做时,不会通过 url 传递任何参数。当我将我f:viewParam value的 in results.xhtml 指向我在 search.xhtml 中使用的同一个支持者时,参数可以很好地通过 url,但该值在我需要的结果支持者中不存在。如果我的 results.xhtml 页面中有重复f:viewParam的 s - 一个带有搜索支持者,一个带有结果支持者,一切正常。两个托管 bean有 2 个相同f:viewParam的 s 是正确的方法吗?

例子:

results.xhtml - 参数通过 url 传递,但在我的 resultsBacker 中不可用

<f:metadata>
  <f:viewParam name="firstName" value="#{searchBacker.firstName}"/>
  <f:viewParam name="lastName" value="#{searchBacker.lastName}"/>
</f:metadata>

results.xhtml - 没有参数通过 url 传递

<f:metadata>
  <f:viewParam name="firstName" value="#{resultsBacker.firstName}"/>
  <f:viewParam name="lastName" value="#{resultsBacker.lastName}"/>
</f:metadata>

results.xhtml - 参数通过 url 传递并在我的 resultsBacker 中可用,但看起来很笨重。这是正确的方法还是我仍然错过了什么?

<f:metadata>
  <f:viewParam name="firstName" value="#{searchBacker.firstName}"/>
  <f:viewParam name="firstName" value="#{resultsBacker.firstName}"/>
  <f:viewParam name="lastName" value="#{searchBacker.lastName}"/>
  <f:viewParam name="lastName" value="#{resultsBacker.lastName}"/>
</f:metadata>
4

2 回答 2

4

我建议您实现两个@ViewScoped托管 bean,一个用于搜索页面,另一个用于结果页面。您还应该有两个 xhtml 页面,每个页面都与一个 bean 相关。显然它的页面将有自己的 url(看起来你现在正在使用同一个 bean)。

您可以使第二页的 bean 期望两个参数,firstName并且lastName. 之后,在preRenderView方法中,当参数已经设置到第二个托管 bean 中时,使用该值查询您的数据库。那么如何实现bean之间的过渡呢?一个结果应该就够了。

<p:button outcome="results">
    <f:param name="firstName" value="#{searchBean.firstName}">
    <f:param name="lastName" value="#{searchBean.lastName}">
</p:button>

这使得 JSF 使用您需要的参数构建一个 url。在您可以执行与您现在正在执行的完全相同的操作之后,但使用您的第二个 bean 来获取您的参数(我强烈建议您不要对该方法使用 getterpreRenderView方法):

<f:metadata>
  <f:event type="preRenderView" listener="#{resultBacker.initialize}" />
  <f:viewParam name="firstName" value="#{resultBacker.firstName}"/>
  <f:viewParam name="lastName" value="#{resultBacker.lastName}"/>
</f:metadata>
于 2013-08-03T15:50:07.673 回答
3

includeViewParams仅当源视图和目标视图都具有声明<f:viewParam>.

因此,在您的特殊情况下,您需要将<f:viewParam>s 与 and 中的 s 都放在相同的name位置。在幕后,即仅获取当前视图的视图参数,然后仅应用也在目标视图中声明的参数。search.xhtmlresults.xhtmlincludeViewParams

也可以看看:


与具体问题无关,您似乎实际上想要一个 GET 表单。在这种情况下,有比使用参数执行 POST-Redirect-GET 更好的方法。查看上述“另请参阅”链接的底部。

于 2013-08-04T16:09:40.110 回答