10

私は遊びを耕してきました!これまでのところ、学習曲線にいくつかのバンプがあります。現在、コントローラーからビューにフラッシュデータを渡すことができません。これは、最初は簡単な作業だと思っていましたが、少なくともそうあるべきです。

これが私が今持っているものです:

私はメインのレイアウトを持っています:application.scala.html

レイアウトに含まれるビューがあります:login.scala.html

コントローラーとメソッドがあります:UX.authenticate()-ログイン試行の結果(成功と失敗)に応じて、ビューにフラッシュデータを提供する必要があります

これは私のコントローラーメソッドのコードです:

def authenticate = Action { implicit request =>
        val (email, password) = User.login.bindFromRequest.get
        // Validation
        // -- Make sure nothing is empty
        if(email.isEmpty || password.isEmpty) {
            flash + ("message" -> "Fields cannot be empty") + ("state" -> "error")
            Redirect(routes.UX.login())
        }
        // -- Make sure email address entered is a service email
        val domain = email.split("@")
        if(domain(1) != "example.com" || !"""(\w+)@([\w\.]+)""".r.unapplySeq(email).isDefined) {
            flash + ("message" -> "You are not permitted to access this service") + ("state" -> "error")
            Redirect(routes.UX.login())
        } else {
            // Attempt login
            if(AuthHelper.login(email, password)) {
                // Login successful
                val user = User.findByEmail(email)
                flash + ("message" -> "Login successful") + ("state" -> "success")
                Redirect(routes.UX.manager()).withSession(
                  session + (
                    "user"      -> user.id.toString
                  )
                )
            } else {
                // Bad login
                flash + ("message" -> "Login failed") + ("state" -> "error")
                Redirect(routes.UX.login())
            }
        }
    }

ログインビューには、次のパラメータがあります。@(implicit flash: Flash)

フラッシュを使おうとすると何も表示されません@flash.get("message")

理想的には@(implicit flash: Flash)、レイアウトを設定して、任意のコントローラーからデータをフラッシュして、自分のビューに到達できるようにします。しかし、それを行うたびに、ログインビューはエラーをスローします。

今の私のログインビューにはこれがあります:

def login = Action { implicit request =>
        flash + ("message" -> "test")
        Ok(views.html.ux.login(flash))
    }

フラッシュデータをビューに渡す理想的な方法は何ですか?どこかに例がありますか?Playの例!フレームワークのドキュメントはまったく役に立ちません。ビューとの相互作用をまったく示さない2つの例に限定されています(下部にあります:http ://www.playframework.com/documentation/2.0/ScalaSessionFlash )。

より簡単な代替手段はありますか?私は何が間違っているのですか?フラッシュデータをレイアウトビューに直接渡すにはどうすればよいですか?

4

2 に答える 2

8

セッションスコープとフラッシュスコープのドキュメントを見ると、次のコードスニペットが表示されます。

def save = Action {
  Redirect("/home").flashing(
    "success" -> "The item has been created"
  )
}

次に、それをフラッシュスコープの使用と比較します。

flash + ("message" -> "Login successful") + ("state" -> "success")

この使用法の問題は、フラッシュが不変であり、再割り当てできないことです。さらに、ここでの使用法では、実際に新しいフラッシュ変数を作成しているだけで、使用されていません。

それを少し変更して次のようにした場合:

implicit val newFlash = flash + ("message" -> "Login successful") + ("state" -> "success")
Redirect(...)

それはうまくいっただろう。ただし、推奨される使用法は.flashing()、結果にこのメソッドを使用することです。このメソッドは、さまざまな結果メソッド(Ok、Redirectなど)が継承するplay.api.mvc.PlainResultに混合されるトレイトであるplay.api.mvc.WithHeadersから取得されます。

次に、ドキュメントに示されているように、テンプレートのフラッシュスコープにアクセスできます。

@()(implicit flash: Flash) ... 
@flash.get("success").getOrElse("Welcome!") ...

編集:ああ、わかりました。サンプルコードを確認しましたが、何をしようとしているのかがわかります。あなたが本当に探しているのは、フォームの送信を処理する標準的な方法だと思います。ここのドキュメントで制約の定義を確認してください。これを実現するためのより良い方法があることがわかると思います。基本的にverifying、フォームをサポートするタプルでメソッドを使用bindFromRequestすると、バインドに失敗し、検証エラーをビューに戻すことができます。

loginForm.bindFromRequest.fold(
  formWithErrors => // binding failure, you retrieve the form containing errors,
    BadRequest(views.html.login(formWithErrors)),
  value => // binding success, you get the actual value 
    Redirect(routes.HomeController.home).flashing("message" -> "Welcome!" + value.firstName)
)
于 2013-03-20T18:54:06.567 に答える
5

人々がこのエラーを回避するのを助けるために、この議論にもう1つ追加したかった:

could not find implicit value for parameter flash: play.api.mvc.Flash

これの多くは冗長であることを私は知っていますが、私の仕事の半分を盗んだ最後の技術があり、私は人々を助けることができると感じています。次のような.flashing(/*フラッシュスコープ情報*/)を追加します。

Redirect(routes.ImageEditApp.renderFormAction(assetId)).
  flashing("error" -> "New filename must be unused and cannot be empty.")

...テンプレートで使用できる暗黙の「フラッシュ」変数を定義します。フラッシュスコープを処理する「ベース」テンプレートがある場合(エラーなど)、ベーステンプレートを1回使用するのは簡単です。 .flashing()を介して暗黙のフラッシュ変数がすでに定義されているため...これは、ベーステンプレートの「インクルード」の1つの例です。

@views.html.base("Editing: "+asset.id, scripts = Some(scripts),
  extraNav = Some(nav))

「flash」変数をベーステンプレートに渡す必要はありません。それは暗黙的です。基本テンプレートはまだそれを定義する必要があります。基本テンプレートのパラメーターは次のとおりです。

@(title: String, stylesheets: Option[Html] = None,
  scripts: Option[Html] = None,
  extraNav: Option[Html] = None)(content: Html)(implicit flash: Flash)

ええ、私はそれの多くが不必要であることを知っています、しかしこれは私がコピーして貼り付けている実世界の例です。とにかく、ベーステンプレートを使用する他のテンプレートが必要になる可能性があり、それらをロードするために常に.flashing()を使用するとは限りません。確かにコントローラーを使用してこれらをロードしているので、次のような暗黙の要求=>でそれぞれのアクションを開始するのを忘れた場合:

def controllerMethodName() = Action { implicit request =>

その場合、暗黙の「フラッシュ」は定義されません。次に、そのテンプレートにベーステンプレートを含めようとすると、デフォルトのフラッシュ暗黙変数が定義されていないために混乱しますが、ベーステンプレートではそれが必要です。したがって、そのエラー。

繰り返しになりますが、修正..すべてのコントローラーメソッドに移動し、暗黙のリクエストを入力するようにしてください=>

于 2013-08-09T19:51:43.570 に答える