java中play方法的两个参数_如何避免在play2中到处传递参数?

在我看来,模板是静态类型的这一事实实际上是一件好事:你可以保证调用你的模板如果编译就不会失败。

但是,它确实在调用站点上添加了一些样板。但是你可以减少它(不会失去静态类型优势)。

在Scala中,我看到了两种实现它的方法:通过动作组合或使用隐式参数。在Java中,我建议使用Http.Context.args映射存储有用的值并从模板中检索它们,而不必显式传递为模板参数。

使用隐式参数

将menus参数放在main.scala.html模板参数的末尾,并将其标记为“隐式”:@(title: String)(content: Html)(implicit menus: Seq[Menu])

@title

@for(menu@menu.name

}    

@content  

现在,如果您有调用此主模板的模板,则可以menus通过mainScala编译器将参数隐式传递给模板,如果它在这些模板中也被声明为隐式参数:@()(implicit menus: Seq[Menu])

@main("SubPage") {

...

}

但是,如果您希望从控制器中隐式传递它,则需要将其作为隐式值提供,可在调用模板的范围内使用。例如,您可以在控制器中声明以下方法:implicit val menu: Seq[Menu] = Menu.findAll

然后在您的操作中,您将能够编写以下内容:def index = Action {

Ok(views.html.index())}def index2 = Action {

Ok(views.html.index2())}

您可以在此博客文章和此代码示例中找到有关此方法的更多信息。

更新:这里也写了一篇很好的博客文章,展示了这种模式。

使用动作组合

实际上,将RequestHeader值传递给模板通常很有用(参见例如此示例)。这不会为控制器代码添加太多样板,因为您可以轻松编写接收隐式请求值的操作:def index = Action { implicit request =>

Ok(views.html.index()) // The `request` value is implicitly passed by the compiler}

因此,由于模板通常至少会接收此隐式参数,因此您可以将其替换为包含例如菜单的更丰富的值。您可以使用Play 2 的动作组合机制来实现。

要做到这一点,你必须定义你的Context类,包装一个基础请求:case class Context(menus: Seq[Menu], request: Request[AnyContent])

extends WrappedRequest(request)

然后,您可以定义以下ActionWithMenu方法:def ActionWithMenu(f: Context => Result) = {

Action { request =>

f(Context(Menu.findAll, request))

}}

哪个可以这样使用:def index = ActionWithMenu { implicit context =>

Ok(views.html.index())}

您可以将上下文作为模板中的隐式参数。例如main.scala.html:@(title: String)(content: Html)(implicit context: Context)

@title

@for(menu @menu.name

}    

@content  

使用操作组合允许您将模板所需的所有隐式值聚合到单个值中,但另一方面,您可能会失去一些灵活性......

使用Http.Context(Java)

由于Java没有Scala的implicits机制或类似机制,如果您想避免显式传递模板参数,可能的方法是将它们存储在Http.Context仅在请求期间存在的对象中。该对象包含args类型的值Map。

因此,您可以从编写拦截器开始,如文档中所述:public class Menus extends Action.Simple {

public Result call(Http.Context ctx) throws Throwable {

ctx.args.put("menus", Menu.find.all());

return delegate.call(ctx);

}

public static List

return (List

}}

静态方法只是从当前上下文中检索菜单的简写。然后注释您的控制器与Menus动作拦截器混合:@With(Menus.class)public class Application extends Controller {

// …}

最后,menus从模板中检索值,如下所示:@(title: String)(content: Html)

@title

@for(menu @menu.name

}    

@content  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值