したがって、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]
を受け入れます。これを行う方法はありますか?ありがとう。
わかりました。バグではないので、Lighthouseの機能応答です。「オプションのパスパラメータを設定しても意味がないため、パスバインド可能オブジェクトのOption [Long]サポートを削除しました。独自のパスパラメータを実装できます。よろしければ、それをサポートするパスバインド可能です。」これまでのところ、私は2つの解決策を持っており、-1をparentIdとして渡しますが、これはあまり好きではありません。または、2つの異なる方法があります。これは、この場合はおそらくより理にかなっています。 PathBindableの実装は今のところあまり実現可能ではないように思われるので、おそらく2つのメソッドを使用することに固執します。
Play2.0はパスパラメータでOption
をサポートしていましたが、Play 2.1はこれをサポートしなくなり、PathBindable forOptionを削除しました。
考えられる解決策の1つは次のとおりです。
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
を実行すると、機能するはずです。オンザフライでバインダーをリロードすると、機能する場合があります。
疑問符を追加する必要があると思います。
controllers.Tasks.addTask(parentId: Option[Long] ?= None)
これから routes-with-optional-parameter 提案は次のようになります:
GET / controllers.Application.show(page = "home")
GET /:page controllers.Application.show(page)
デフォルト値を渡さなくても問題を解決する簡単な方法は、パラメーターをオプションでラップする簡単なプロキシメソッドを追加することです。
ルート:
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))
パスを_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
_のように見えることを期待して機能します