将 html 表单操作绑定到采用某些参数的控制器方法

Binding an html form action to a controller method that takes some parameters

在我的查找控制器中,我有一个类似的方法:

public Result findLatest(String repoStr) {
    ............
}

通过路由链接:

GET     /latest                     controllers.Find.findLatest(repo: String)

然后,我在视图中有一个表单:

<form action="@routes.Find.findLatest()" method="get">
    ....
    <select name="repo">....</select>
</form>

但显然这是失败的,因为它需要一些我在操作中没有满足的参数。执行此操作的正确方法是什么,而不必在我的控制器中留下不带参数的 findLatest 方法?

通常所有表单数据都在正文中,您可以使用 bindFromRequest() 在操作方法中检索它们(参见 docs)。

如果您真的想将一个表单元素作为 URL 的一部分传递,那么您必须在 JavaScript 中动态编写 URL 并更改路线。

您的路线可能如下所示:

GET     /latest/:repo                     controllers.Find.findLatest(repo: String)

还有 JavaScript 部分(我实际上并没有测试代码):

<form name="myform" action="javascript:composeUrl();" method="get">
   ....
   <select name="repo">....</select>
</form>

<script>
  function submitform() {
    var formElement = document.getElementsByName("myform");
    var repo = formElement.options[e.selectedIndex].text;
    formElement.action = "/lastest/" + repo;
    formElement.submit();
  }
</script>

您可以更改路由以接受空字符串:

GET     /latest/:repo          controllers.Find.findLatest(repo: String = "")

然后配置你的控制器函数来处理空字符串。

这样,

<form action="@routes.Find.findLatest()" method="get">
....
<select name="repo">....</select>

将在控制器级别将 repo 评估为空字符串。

编辑: Play v 2.1 中删除了对该实现的支持

您可能对 Play 的可选参数感兴趣,例如play.libs.F.Option[字符串]

示例:How to handle optional query parameters in Play framework

GET     /latest/:repo/:artifact     controllers.Find.findLatestArtifact(repo: play.libs.F.Option[String], artifact: play.libs.F.Option[String])

这将使您可以灵活地选择需要提供的参数。

不确定您使用的是哪种语言,但上面的 link 包含一个 scala 示例,java 中的方法声明类似于:

import play.libs.F.Option;
public static Result findLatestArtifact(Option<String> repo, Option<String> artifact){ ... }

并更新了实施 2.1 Routes with optional parameter - Play 2.1 Scala

编辑: 玩 2.1+ 支持:支持下面的@RobertUdah

正在初始化为空:

GET     /latest/               controllers.Find.findLatest(repo: String = null)
GET     /latest/:repo          controllers.Find.findLatest(repo: String)

<form action="@routes.Find.findLatest()" method="get">

Cavice 提出了一些我认为是最佳解决方案的建议(因为 Play 2.1 中的默认活页夹不再支持 F.Option)。

我最终离开了这样的路线:

GET     /latest                     controllers.Find.findLatest(repo=null)

和这样的观点:

<form action="@routes.Find.findLatest(null)" method="get">
    <select name="repo"> .... </select>
....
</form>

在控制器中:

public Result findLatest(String repoStr) {
    if(repoStr==null) {
        repoStr=Form.form().bindFromRequest().get("repo");
.....

这让我有第二条路线:

GET     /latest/:repo                     controllers.Find.findLatest(repo: String)