在Play Framework 2(Java)中处理表单中的错误时,我想提供一条警告用户出错的全面错误消息,例如: " 表格X未更新"。一种方法是,除了每个表单字段的错误之外,还要创建一个全局错误,然后在每个模板上显示:
控制器:
if(form.hasErrors()) {
form.reject("Form X not updated."); // This creates a global error
}
模板:
@if(form.hasGlobalErrors) {
@someFunctionToPresentErrors(from.globalError.message))
}
但是,将这段相同的代码添加到包含表单的每个模板都违反了DRY原则。
到目前为止,我最好的解决方案是将错误消息添加到Http.Context
,然后拦截每个模板调用的主模板中的错误消息:
控制器:
Http.Context.current().args.put("error", "Form X not updated.");
主要模板:
@if(Http.Context.current().args.containsKey("error")){
@someFunctionToPresentErrors(
Http.Context.current().args.get("error").asInstanceOf[String])
}
这样做更好,因为它允许我将错误演示文稿内容保存在一个地方,但感觉就像滥用Http.Context
一样。请注意,flash(...)
也可用于隐式传递变量并提供与Http.Context
相同的效果,但在调用badRequest(...)
时不允许这样做,因为闪存只应用于重定向。无论如何,我认为应该有更好的方法来使用Play Framework提供的表单机制。
这是最好的做法吗?
答案 0 :(得分:4)
我认为你在这种情况下高估了 DRY违规 - 实际上我意识到即使全球错误也不是全球性的 - 实际上每种形式都有它&#39 ;自己的背景。无论如何,为了加快工作速度,您可以使用template tags和Flash scope
首先添加两个通用公共方法,即Application
控制器
public static void flashGlobalError() {
flashGlobalError("Oppps... error occurred and I don't know the reason ;(");
}
public static void flashGlobalError(String msg) {
flash("globalError", msg);
}
然后创建无参数tag template,即views/tags/globalErrorByFlash.scala.html
@if(flash.get("globalError")) {
<div style="background: red">
<h4>Error!</h4>
@flash.get("globalError")
</div>
}
并将其包含在您的main
模板中(或仅限于所选视图中):
<body>
@tags.globalErrorByFlash()
@content
</body>
因此,每当您想要显示此错误时,您都可以在您的操作中执行此操作:
if(form.hasErrors()) {
Application.flashGlobalError();
return badRequest(...);
}
或
if(form.hasErrors()) {
Application.flashGlobalError("This case is quite bit different...");
return badRequest(...);
}
这种方法的最大好处是您不需要依赖Form.form(T)
,因为您可以在任何地方使用它:
if (1 != 0){
Application.flashGlobalError("Stupido! One isn't equal to Zero!");
}
最后:请记住,闪存范围中保留的任何值仅适用于一个请求,因此重定向后可能会消失。视图/模板渲染也会计算在内,因此如果您将错误重定向到新操作,请将其转发到控制器中,以便重定向视图可以看到它。