15

所以在 Play 2.0 中我有这个:

GET     /tasks/add              controllers.Tasks.addTask(parentId: Option[Long] = None)
GET     /tasks/:parentId/add    controllers.Tasks.addTask(parentId: Option[Long])

使用这样的控制器方法:

def addTask(parentId: Option[Long]) = Action { 
    Ok(views.html.addTask(taskForm, parentId))  
}

它正在工作。当我迁移到 2.1 时,它似乎抱怨这些行:No URL path binder found for type Option[Long]. Try to implement an implicit PathBindable for this type.基本上,我想要完成的是让 routetasks/add和 routetasks/123/add链接到接受Optional[Long]. 知道怎么做吗?谢谢。

好的,所以我得到了一种它不是错误,它是 Lighthouse 上的功能响应:“我们删除了路径可绑定中的 Option[Long] 支持,因为拥有可选路径参数没有意义。您可以实现自己的如果你愿意,可以支持它的路径可绑定。” 到目前为止,我有 2 个解决方案,将 -1 作为 parentId 传递,我不太喜欢。或者有两种不同的方法,在这种情况下可能更有意义。现在实现 PathBindable 似乎不太可行,所以我可能会坚持使用 2 种方法。

4

5 回答 5

15

路径参数支持 Play 2.0 Option,Play 2.1 不再支持,他们删除了 Option 的 PathBindable。

一种可能的解决方案是:

package extensions
import play.api.mvc._
object Binders {
  implicit def OptionBindable[T : PathBindable] = new PathBindable[Option[T]] {
    def bind(key: String, value: String): Either[String, Option[T]] =
      implicitly[PathBindable[T]].
        bind(key, value).
        fold(
          left => Left(left),
          right => Right(Some(right))
        )

    def unbind(key: String, value: Option[T]): String = value map (_.toString) getOrElse ""
  }
}

并将其添加到Build.scalausing routesImport += "extensions.Binders._". 运行play clean ~run它应该可以工作。动态重新加载活页夹有时才有效。

于 2013-02-20T16:26:06.450 回答
6

我认为您必须添加一个问号:

controllers.Tasks.addTask(parentId: Option[Long] ?= None)

于 2013-02-20T14:19:12.270 回答
5

从这个带有可选参数的路由中,建议如下:

GET   /                     controllers.Application.show(page = "home")
GET   /:page                controllers.Application.show(page)
于 2013-02-20T14:31:47.570 回答
2

您的问题的简单解决方案,无需传递默认值,是添加一个简单的代理方法,将参数包装在一个选项中。

路线:

GET     /tasks/add              controllers.Tasks.addTask()
GET     /tasks/:parentId/add    controllers.Tasks.addTaskProxy(parentId: Long)

控制器:

def addTask(parentId: Option[Long] = None) = Action { 
    Ok(views.html.addTask(taskForm, parentId))  
}

def addTaskProxy(parentId: Long) = addTask(Some(parentId))
于 2016-08-06T01:06:52.640 回答
1

我有同样的事情,如果你指定 passGET/foo:id并且controllers.Application.foo(id : Option[Long] ?= None)你在另一边得到一个错误It is not allowed to specify a fixed or default value for parameter: 'id' extracted from the path,你可以按照以下方式做GET/foo controllers.Application.foo(id : Option[Long] ?= None),它会工作,期待你的请求看起来像.../foo?id=1

于 2013-02-20T17:08:55.917 回答