5

次のように実装されたコントローラーアクションが1つあります。

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 

次にコンパイルします...しかし、なぜですか?

4

2 に答える 2

8

探しているのはImplicit Parametersです。要するに:

暗黙的なパラメーターは、通常のパラメーターまたは明示的なパラメーターと同じように渡すことができます。暗黙的なパラメーターを明示的に指定しない場合、コンパイラーはパラメーターを渡そうとします。暗示はさまざまな場所から発生する可能性があります。FAQ からScala はどこで暗黙を探すのですか? :

  1. 現在のスコープの最初のルック
    • 現在のスコープで定義されている暗黙
    • 明示的なインポート
    • ワイルドカードのインポート
  2. 関連する型を見てみましょう
    • タイプのコンパニオン オブジェクト
    • 引数の型の暗黙のスコープ (2.9.1)
    • 型引数の暗黙のスコープ (2.8.0)
    • ネストされた型の外部オブジェクト
    • その他の寸法

番号 1 の下の暗黙的なものは、番号 2 の下のものよりも優先されます。

request例のようにマークimplicitすることで、「現在のスコープで定義された暗黙的」を宣言しています。bindFormRequestリクエストを渡すように「要求」するため、暗黙のリクエストを配置する必要があります。その署名を参照してください。

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

implicit requestスコープ内にあるので、コンパイラはそれを自動的に に渡しますbindFormRequerst

request最初に述べたように、明示的に渡すこともできます。

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

後者の場合、明らかに明示的に渡しているため、 asrequestを宣言する必要はありません。どちらのバリアントも同じです。どちらを好むかはあなた次第です。implicitrequest

于 2016-12-12T08:21:17.483 に答える
2

implicit request次のようなスコープが必要です: https://github.com/pedrorijo91/play-slick3-steps/blob/master/app/controllers/ApplicationController.scala#L11

于 2016-12-11T21:25:50.370 に答える