簡體   English   中英

如何通過播放將Flash數據從控制器傳遞到視圖!骨架

[英]How to pass flash data from controller to view with Play! framework

我一直在玩耍! 到目前為止,學習曲線有一些障礙。 現在我無法將閃存數據從控制器傳遞到視圖,起初我認為這是一項微不足道的任務,或者至少它應該是。

這就是我現在所擁有的:

我有一個主要的布局:application.scala.html

我有一個在布局中的視圖:login.scala.html

我有我的控制器和方法:UX.authenticate() - 我希望這根據登錄嘗試的結果向視圖提供flash數據(成功與失敗)

這是我的控制器方法中的代碼:

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))
    }

將Flash數據傳遞給視圖的理想方式是什么?有哪些示例? 關於Play的例子! 框架文檔沒有任何幫助,並且僅限於兩個顯示根本沒有與視圖交互的示例(位於底部: http//www.playframework.com/documentation/2.0/ScalaSessionFlash )。

有更簡單的選擇嗎? 我究竟做錯了什么? 如何將Flash數據直接傳遞到布局視圖?

如果您查看Session和Flash范圍的文檔,您將看到以下代碼段:

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

現在,將其與您使用閃存范圍進行比較:

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

這種用法的問題是flash是不可變的,你無法重新分配它。 此外,根據您的使用情況,您實際上是在創建一個新的Flash變量,它只是沒有被使用。

如果你稍微修改了一下就變成:

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

它會奏效。 但是,首選用法是對結果使用.flashing()方法。 這個方法來自play.api.mvc.WithHeaders,這是一個混合到play.api.mvc.PlainResult中的特性,其中包含各種結果方法(Ok,Redirect等)。

然后,如文檔中所示,您可以訪問模板中的Flash范圍:

@()(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)
)

想在本次討論中再添一句,以幫助人們避免這個錯誤:

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

我知道其中很多都是多余的,但最后有一個技術性能偷走了我工作日的一半,我覺得我可以幫助別人。 附加.flashing(/ *你的flash范圍信息* /),例如:

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

... 確實定義了可以在模板中使用的隱式“flash”變量,如果你有一個“基礎”模板,你想要處理閃存范圍(例如錯誤),基本模板的單一使用很容易,因為你已經通過.flashing()定義了隱式flash變量...這是我的一個基礎模板“包含”的例子。

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

不必到“閃”變量傳遞給基本模板。 這是隱含的。 基本模板仍然需要定義它。 我的基本模板的參數是這樣的:

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

是的,我知道很多這是不必要的,但這是一個真實世界的例子,我正在復制n'粘貼。 無論如何,您可能需要使用其他模板來使用基本模板,並且您並不總是使用.flashing()來加載它們。 由於您肯定使用控制器加載它們,如果您忘記使用隱式請求=>啟動每個操作,例如:

def controllerMethodName() = Action { implicit request =>

那么隱藏的“flash”將不會被定義。 然后,當該模板試圖包含您的基本模板時,您將陷入困境,因為您沒有定義默認的Flash隱式變量,而基本模板需要它。 因此,這個錯誤。

所以再次,修復..轉到所有的控制器方法,並確保你輸入隱含的請求=>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM