web-dev-qa-db-ja.com

オプションのパラメーターを使用したルート-Play2.1 Scala

したがって、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つのメソッドを使用することに固執します。

14
Laky

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を実行すると、機能するはずです。オンザフライでバインダーをリロードすると、機能する場合があります。

14
Marius Soutier

疑問符を追加する必要があると思います。

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

7
cmacher

これから routes-with-optional-parameter 提案は次のようになります:

GET   /                     controllers.Application.show(page = "home")
GET   /:page                controllers.Application.show(page)
5
korefn

デフォルト値を渡さなくても問題を解決する簡単な方法は、パラメーターをオプションでラップする簡単なプロキシメソッドを追加することです。

ルート:

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))
2
user267817

パスを_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_のように見えることを期待して機能します

0
arussinov