【问题标题】:Binding an html form action to a controller method that takes some parameters将 html 表单操作绑定到带有一些参数的控制器方法
【发布时间】:2015-09-22 16:59:19
【问题描述】:

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

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 方法在我的控制器中不带任何参数?

【问题讨论】:

    标签: forms playframework controller action


    【解决方案1】:

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

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

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

    这样,

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

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

    【讨论】:

      【解决方案2】:

      编辑:在 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])
      

      这将使您能够灵活地提供需要提供的参数。

      不确定您使用的是哪种语言,但上面的链接包含 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">
      

      【讨论】:

      • 谢谢,唯一的小问题是他们在 Play 2.1 中删除了 Option 的路径绑定器。来自 stackoverflow 的另一篇文章:好的,所以:“我们删除了路径可绑定中的 Option[Long] 支持,因为拥有可选的路径参数没有意义。如果您愿意,您可以实现自己的路径可绑定来支持它。”但是在我看来,传递一个 Optional 而不是一些任意值似乎要好得多。这不就是我们一开始就有可选项的原因吗?也许我宁愿在这种情况下创建 2 种不同的方法,因为这比将 -1 作为 id 传递更有意义。
      • @Ruben 啊,你是对的。这不适用于 2.1+。另一种选择是将您的命名参数转换为查询参数,例如而不是 /latest/repo/artifact 你的 url 看起来类似于 /latest?repo=somerepo&artifact=someartifact 支持 2.1+。很抱歉造成混乱。
      • 如果您仍然想要空的命名参数,@RobertUdah's Answer 会更好地为您工作。如果您坚持进行 repoStr != null 检查(vs repoStr != null && !isEmpty()),您可以在路由中将 String 初始化为 null。例如GET /latest/:repo controllers.Find.findLatest(repo: String = null) GET /latest/:repo controllers.Find.findLatest(repo: String) 。这将使您不必将 null 放在您的视图中,并允许 Robert 的清洁器
      【解决方案3】:

      通常所有表单数据都在正文中,您可以使用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>
      

      【讨论】:

        【解决方案4】:

        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)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-04-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多