【问题标题】:How Action works in Play frameworkAction 在 Play 框架中的工作原理
【发布时间】:2014-01-24 22:06:47
【问题描述】:

如果我理解正确的话

    object Application extends Controller {
    def page1 = Action { Ok("Hello") } 
    }

可以写成

    object Application extends Controller {
    val f : Result = { Ok("Hello") }
    def page1 = Action( f )
    // i.e. Action.apply( f )
    }

documentation 表示动作本质上是一个 (Request[A] => Result) 函数,它处理请求并生成要发送给客户端的结果。

由于 Action 本质上是一个函数,我们可以将函数 f 应用于 Action,即 Action.apply(f)。希望到目前为止我是正确的。

下面这段代码,

    def index = Action { implicit request =>
    Async {
      val cursor = collection.find(
        BSONDocument(), BSONDocument()).cursor[Patient] 
        val futureList = cursor.toList 
        futureList.map { patients => Ok(Json.toJson(patients)) } 
      }
    }

如果我要写作

    def index = Action(f)

我希望能够编写一个函数 f。我的伪代码是

    val f: Result = 
      //a function that takes Request[A] and returns Result
      {
        (request :Request[A]) => 
            Async {
              val cursor = collection.find(
                BSONDocument(), BSONDocument()).cursor[Patient] 
              val futureList = cursor.toList 
              futureList.map { patients => Ok(Json.toJson(patients)) } 
            }
      }

而且我仍在努力使这项工作正常进行。编写函数的任何帮助都会有所帮助。

【问题讨论】:

    标签: scala playframework functional-programming


    【解决方案1】:

    当它实际上是 Request[_] => Result 时,你的 f 类型是 Result

    f 的正确版本如下:

    val f: Request[_] => Result = request =>
       Async {
          val cursor = collection.find(
             BSONDocument(), BSONDocument()).cursor[Patient] 
          val futureList = cursor.toList 
          Ok(Json.toJson(futureList ))
      }
    }
    

    注意Request[_] 不能有泛型类型参数。要使 Request 是通用的,f 必须是 def 而不是 val。

    另外,如果futureList 是一个列表,那么map 将生成一个Result 的列表,而不是一个Result。假设您想要光标中所有患者的 JSON 列表,我进行了更正。

    【讨论】:

    • 不是原问题的一部分,但你能解释一下request前面隐含关键字的用途吗?谢谢。
    • 如果你不熟悉implicits,我推荐docs.scala-lang.org/tutorials/tour/implicit-parameters.html。在这种情况下,将请求标记为隐式会导致它自动应用于操作中采用隐式请求参数的任何函数调用。这很有用,因为在 Web 应用程序中,通常需要访问控制器外部的请求(例如,如果请求上有用户 ID)。因此,通过将请求标记为隐式并将任何需要请求的函数标记为隐式,请求信息始终自动可用。
    【解决方案2】:

    感谢您的回复。我用过

        val f: Request[_] => Result = 
          //a function that takes Request[A] and returns Result
          {
             (request : Request[_]) => 
                Async {
                  val cursor = collection.find(
                    BSONDocument(), BSONDocument()).cursor[Patient] 
                  val futureList = cursor.toList 
                  futureList.map { patients => Ok(Json.toJson(patients)) } 
                }
          }
    

    希望这是 f 的正确写法,它接受一个 Request[_] 并返回一个 Result。

    【讨论】:

      猜你喜欢
      • 2011-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-19
      • 2015-04-23
      • 1970-01-01
      • 2018-10-16
      相关资源
      最近更新 更多