如何通过播放将Flash数据从控制器传递到视图!骨架

Ron*_*Ron 10 scala playframework playframework-2.0

我一直在玩耍!到目前为止,学习曲线有一些障碍.现在我无法将闪存数据从控制器传递到视图,起初我认为这是一项微不足道的任务,或者至少它应该是.

这就是我现在所拥有的:

我有一个主要的布局: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())
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

在我的登录视图中,我有一个参数: @(implicit flash: Flash)

当我尝试使用闪光灯时,似乎没有使用 @flash.get("message")

理想情况下,我想@(implicit flash: Flash)在布局中设置,以便我可以从任何控制器闪存数据,它将到达我的视图.但每当我这样做时,登录视图会抛出错误.

在我的登录视图中,我现在有:

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

将Flash数据传递给视图的理想方式是什么?有哪些示例?关于Play的例子!框架文档没有任何帮助,并且仅限于两个显示根本没有与视图交互的示例(位于底部:http://www.playframework.com/documentation/2.0/ScalaSessionFlash).

有更简单的选择吗?我究竟做错了什么?如何将Flash数据直接传递到布局视图?

Rya*_*yan 8

如果您查看Session和Flash范围的文档,您将看到以下代码段:

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

现在,将其与您使用闪存范围进行比较:

flash + ("message" -> "Login successful") + ("state" -> "success")
Run Code Online (Sandbox Code Playgroud)

这种用法的问题是flash是不可变的,你无法重新分配它.此外,根据您的使用情况,您实际上是在创建一个新的Flash变量,它只是没有被使用.

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

implicit val newFlash = flash + ("message" -> "Login successful") + ("state" -> "success")
Redirect(...)
Run Code Online (Sandbox Code Playgroud)

它会奏效.但是,首选用法是.flashing()在结果上使用该方法.这个方法来自play.api.mvc.WithHeaders,这是一个混合到play.api.mvc.PlainResult中的特性,其中包含各种结果方法(Ok,Redirect等).

然后,如文档中所示,您可以访问模板中的Flash范围:

@()(implicit flash: Flash) ... 
@flash.get("success").getOrElse("Welcome!") ...
Run Code Online (Sandbox Code Playgroud)

编辑:啊,好的.我已经查看了您的示例代码,现在我看到您正在尝试做什么.我认为你真正想要的是处理表单提交的规范方式.查看约束定义这里的文件中,我想你会看到有一个更好的方式来做到这一点.本质上,您将需要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)
)
Run Code Online (Sandbox Code Playgroud)


sda*_*zig 5

想在本次讨论中再添一句,以帮助人们避免这个错误:

could not find implicit value for parameter flash: play.api.mvc.Flash
Run Code Online (Sandbox Code Playgroud)

我知道其中很多都是多余的,但最后有一个技术性能偷走了我工作日的一半,我觉得我可以帮助别人.附加.flashing(/*你的flash范围信息*/),例如:

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

... 确实定义了可以在模板中使用的隐式"flash"变量,如果你有一个"基础"模板,你想要处理闪存范围(例如错误),基本模板的单一用法很容易,因为你已经通过.flashing()定义了隐式flash变量...这是我的一个基础模板"包含"的例子.

@views.html.base("Editing: "+asset.id, scripts = Some(scripts),
  extraNav = Some(nav))
Run Code Online (Sandbox Code Playgroud)

不是要"闪"变量传递给基本模板.这是隐含的.基本模板仍然需要定义它.我的基本模板的参数是这样的:

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

是的,我知道很多这是不必要的,但这是一个真实世界的例子,我正在复制n'粘贴.无论如何,您可能需要使用其他模板来使用基本模板,并且您并不总是使用.flashing()来加载它们.由于您肯定使用控制器加载这些,因此如果您忘记使用隐式请求=>启动每个操作,例如:

def controllerMethodName() = Action { implicit request =>
Run Code Online (Sandbox Code Playgroud)

那么隐藏的"flash"将不会被定义.然后,当该模板试图包含您的基本模板时,您将陷入困境,因为您没有定义默认的Flash隐式变量,而基本模板需要它.因此,这个错误.

所以再次,修复..转到所有的控制器方法,并确保你输入隐含的请求=>!