所以在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.
基本上,我想要完成的是将路由tasks/add
和路由tasks/123/add
链接到相同的方法接受Optional[Long]
。知道怎么做吗?感谢。
好的,所以我得到了一种不是bug,它是Lighthouse上的一个功能响应:“我们删除了路径绑定中的Option [Long]支持,因为拥有可选路径参数没有意义。你可以如果你愿意,可以实现你自己的路径可绑定支持它。“到目前为止,我有2个解决方案,传递-1作为parentId,我不太喜欢。或者有两种不同的方法,在这种情况下可能更有意义。实现PathBindable现在似乎不太可行,所以我可能会坚持使用2种方法。
答案 0 :(得分:14)
播放2.0支持Option
路径参数,Play 2.1不再支持此功能,他们删除了选项的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.scala
将其添加到routesImport += "extensions.Binders._"
。运行play clean ~run
,它应该工作。只在运行中重新加载粘合剂有时会起作用。
答案 1 :(得分:7)
我认为你必须添加一个问号:
controllers.Tasks.addTask(parentId: Option[Long] ?= None)
答案 2 :(得分:5)
从routes-with-optional-parameter开始,建议如下:
GET / controllers.Application.show(page = "home")
GET /:page controllers.Application.show(page)
答案 3 :(得分: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))
答案 4 :(得分:0)
我有同样的事情,如果您将通行证指定为GET/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