Scala Play 2.5 Form bindFromRequest:在这里找不到任何HTTP请求?

eiee3dmh  于 6个月前  发布在  Scala
关注(0)|答案(2)|浏览(83)

我有一个这样实现的控制器操作:

def doChangePassword = deadbolt.Restrict(List(Array(Application.USER_ROLE_KEY)))() 
{ request => // <<<<<<<<<<<< here is the request 
  Future {
    val context = JavaHelpers.createJavaContext(request)
    com.feth.play.module.pa.controllers.AuthenticateBase.noCache(context.response())

    val filledForm = Account.PasswordChangeForm.bindFromRequest
    // compilation error here, it can't see the request ^^^^^^^

    if (filledForm.hasErrors) {
      // User did not select whether to link or not link
      BadRequest(views.html.account.password_change(userService, filledForm))
    } else {
      val Some(user: UserRow) = userService.getUser(context.session)
      val newPassword = filledForm.get.password
      userService.changePassword(user, new MyUsernamePasswordAuthUser(newPassword), true)
      Redirect(routes.Application.profile).flashing(
        Application.FLASH_MESSAGE_KEY -> messagesApi.preferred(request)("playauthenticate.change_password.success")
      )
    }
  }
}

字符串
上面的实现会导致编译错误:

[error] /home/bravegag/code/play-authenticate-usage-scala/app/controllers/Account.scala:74: Cannot find any HTTP Request here
[error]         val filledForm =  Account.PasswordChangeForm.bindFromRequest
[error]                                                     ^
[error] one error found


但是,如果我将第2行从:

{ request => // <<<<<<<<<<<< here is the request


{ implicit request => // <<<<<<<<<<<< here is the request


然后编译,但为什么呢

x759pob2

x759pob21#

您正在寻找的是Implicit Parameters。简而言之:
隐式参数可以像常规参数或显式参数一样传递。如果您没有显式提供隐式参数,那么编译器将尝试为您传递一个。隐式参数可以来自各种地方。来自FAQ Where does Scala look for implicits?
1.首先查看当前范围

  • 在当前作用域中定义的implant
  • 显式导入
  • 中国进口

1.现在查看

  • 类型的伴随对象
  • 参数类型的隐式作用域(2.9.1)
  • 类型参数的隐式作用域(2.8.0)
  • 嵌套类型的外部对象
  • 其他尺寸

在第1项下隐含。优先于第2项下的。
在你的例子中,通过将request标记为implicit,你声明了一个“Implicit defined in current scope”。你需要有一个隐式请求,因为bindFormRequest“要求”你传递一个请求。参见它的签名:

bindFromRequest()(implicit request: Request[_]): Form[T]

字符串
现在你已经在作用域中有了一个implicit request,编译器会自动将它传递给bindFromRequest
正如我在开始时提到的,你也可以显式地传递request

val filledForm = Account.PasswordChangeForm.bindFromRequest()(request)


在后一种情况下,没有必要将request声明为implicit,因为显然你是显式传递request。两种变体都是相等的。你可以选择哪一种。

sg2wtvxw

sg2wtvxw2#

在作用域中需要一个implicit request,如下所示:https://github.com/pedrorijo91/play-slick3-steps/blob/master/app/controllers/ApplicationController.scala#L11

相关问题