首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何避免在play2中到处传递参数?

如何避免在play2中到处传递参数?
EN

Stack Overflow用户
提问于 2012-03-09 13:14:46
回答 3查看 41.5K关注 0票数 125

在play1中,我通常在操作中获取所有数据,直接在视图中使用它们。因为我们不需要在视图中显式声明参数,所以这非常简单。

但是在play2中,我发现我们必须在视图的头部声明所有的参数(包括request),在操作中获取所有数据并将它们传递到视图中将非常乏味。

例如,如果我需要在首页显示从数据库加载的菜单,我必须在main.scala.html中定义它

代码语言:javascript
复制
@(title: String, menus: Seq[Menu])(content: Html)    

<html><head><title>@title</title></head>
<body>
    <div>
    @for(menu<-menus) {
       <a href="#">@menu.name</a>
    }
    </div>
    @content
</body></html>

然后我必须在每个子页面中声明它:

代码语言:javascript
复制
@(menus: Seq[Menu])

@main("SubPage", menus) {
   ...
}

然后,我必须获取菜单,并在每个操作中将其传递给视图:

代码语言:javascript
复制
def index = Action {
   val menus = Menu.findAll()
   Ok(views.html.index(menus))
}

def index2 = Action {
   val menus = Menu.findAll()
   Ok(views.html.index2(menus))
}

def index3 = Action {
   val menus = Menu.findAll()
   Ok(views.html.index(menus3))
}

现在它在main.scala.html中只有一个参数,如果有多个呢?

所以最后,我决定把所有的Menu.findAll()都直接放在视图中:

代码语言:javascript
复制
@(title: String)(content: Html)    

<html><head><title>@title</title></head>
<body>
    <div>
    @for(menu<-Menu.findAll()) {
       <a href="#">@menu.name</a>
    }
    </div>
    @content
</body></html>

我不知道它是好的还是推荐的,有没有更好的解决方案?

EN

回答 3

Stack Overflow用户

发布于 2012-12-17 15:02:16

我支持stian的回答。这是获得结果的一种非常快速的方法。

我刚从Java+Play1.0迁移到Java+Play2.0,到目前为止,模板是最难的部分,也是我找到的实现基本模板(标题、标题等)的最好方法。就是通过使用Http.Context。

有一个非常好的语法,你可以用标签来实现。

代码语言:javascript
复制
views
  |
  \--- tags
         |
         \------context
                  |
                  \-----get.scala.html
                  \-----set.scala.html

其中,get.scala.html是:

代码语言:javascript
复制
@(key:String)
@{play.mvc.Http.Context.current().args.get(key)}

set.scala.html是:

代码语言:javascript
复制
@(key:String,value:AnyRef)
@{play.mvc.Http.Context.current().args.put(key,value)}

意味着您可以在任何模板中编写以下代码

代码语言:javascript
复制
@import tags._
@context.set("myKey","myValue")
@context.get("myKey")

所以它的可读性和美感都很好。

这就是我选择的方式。stian -好的建议。证明了向下滚动查看所有答案的重要性。:)

传递HTML变量

我还没有弄清楚如何传递Html变量。

@(标题:String,内容:Html)

但是,我知道如何将它们作为块传递。

@(title:String)(content:Html)

因此,您可能希望将set.scala.html替换为

代码语言:javascript
复制
@(key:String)(value:AnyRef)
@{play.mvc.Http.Context.current().args.put(key,value)}

这样,您就可以像这样传递Html块

代码语言:javascript
复制
@context.set("head"){ 
     <meta description="something here"/> 
     @callSomeFunction(withParameter)
}

编辑:我的"Set“实现的副作用

一个常见的用例:它的模板继承。

您有一个base_template.html,然后您有一个扩展base_template.html的page_template.html。

base_template.html可能看起来像这样

代码语言:javascript
复制
<html> 
    <head>
        <title> @context.get("title")</title>
    </head>
    <body>
       @context.get("body")
    </body>
</html>

而页面模板可能看起来像这样

代码语言:javascript
复制
@context.set("body){
    some page common context here.. 
    @context.get("body")
}
@base_template()

然后您有一个页面(假设是login_page.html),如下所示

代码语言:javascript
复制
@context.set("title"){login}
@context.set("body"){
    login stuff..
}

@page_template()

这里需要注意的重要一点是,您设置了两次"body“。一次在"login_page.html“中,然后在"page_template.html”中。

这似乎会触发一个副作用,只要你像我上面建议的那样实现set.scala.html。

代码语言:javascript
复制
@{play.mvc.Http.Context.current().put(key,value)}

因为页面会显示“登录资料...”两次,因为put返回了第二次放入相同键时弹出的值。(参见在java文档中放入签名)。

scala提供了一种更好的修改map的方法

代码语言:javascript
复制
@{play.mvc.Http.Context.current().args(key)=value}

不会引起这种副作用。

票数 14
EN

Stack Overflow用户

发布于 2012-12-12 18:14:04

如果您正在使用Java,并且只想以最简单的方式访问HTTP上下文,而不必编写拦截器和使用@With注释,那么您也可以直接从模板访问HTTP上下文。

例如,如果您需要模板中提供的变量,您可以使用以下命令将其添加到HTTP上下文中:

代码语言:javascript
复制
Http.Context.current().args.put("menus", menus)

然后,您可以使用以下命令从模板访问它:

代码语言:javascript
复制
@Http.Context.current().args.get("menus").asInstanceOf[List<Menu>]

显然,如果你用Http.Context.current().args.put("","")来乱用你的方法,你最好使用一个拦截器,但对于简单的情况,它可能会起作用。

票数 13
EN

Stack Overflow用户

发布于 2013-03-24 08:42:04

从Stian的回答中,我尝试了一种不同的方法。这对我很有效。

在JAVA代码中

代码语言:javascript
复制
import play.mvc.Http.Context;
Context.current().args.put("isRegisterDone", isRegisterDone);

在HTML模板标题中

代码语言:javascript
复制
@import Http.Context
@isOk = @{ Option(Context.current().args.get("isOk")).getOrElse(false).asInstanceOf[Boolean] } 

并像这样使用

代码语言:javascript
复制
@if(isOk) {
   <div>OK</div>
}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9629250

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档