Playframework 在Play框架中传递公共状态

Playframework 在Play框架中传递公共状态,playframework,Playframework,关于将公共状态传递给模板,我或多或少有一个理解Play框架的一般性问题。这是一个广泛讨论的话题,如下所示: 但我仍然不确定最佳实践是什么。我熟悉基于脚本语言的MVC框架,比如CakePHP或Django,所以这个问题对我来说并不重要。 因此,基本上有两种可能性: 在模板中使用隐式变量,这只适用于Scala,您仍然必须在每个模板中声明该变量 使用Http.Context类来存储数据,这在我看来更像是一种黑客行为,不适合传递大量数据。(如果我错了,请纠正我) 对于这个问题,我有两个重要的用例。第

关于将公共状态传递给模板,我或多或少有一个理解Play框架的一般性问题。这是一个广泛讨论的话题,如下所示: 但我仍然不确定最佳实践是什么。我熟悉基于脚本语言的MVC框架,比如CakePHP或Django,所以这个问题对我来说并不重要。 因此,基本上有两种可能性:

  • 在模板中使用隐式变量,这只适用于Scala,您仍然必须在每个模板中声明该变量
  • 使用Http.Context类来存储数据,这在我看来更像是一种黑客行为,不适合传递大量数据。(如果我错了,请纠正我)
对于这个问题,我有两个重要的用例。第一个是让登录的用户对象在任何地方都可用。这是使用Http.Context非常容易解决的问题。第二个对我来说更难。我有一个标题,显示登录表单或一些用户特定的选项。因此,我在模板中有一个if条件,检查用户是否登录。但是当我显示登录表单时,我需要在控制器中生成表单对象。因此,我必须在每个控制器中生成该对象,并将其传递给每个模板,尽管我只需要在没有用户登录时使用它。我敢肯定,游戏框架的制作人是否就是这么说的

我会很高兴有任何见解或冲动。
谢谢。

对于显示表单,您可以调用一个方法来创建表单并呈现模板,而不只是调用另一个模板

例如,您可以使用一个模板来显示用户信息或表单,如下所示:

views/home.scala.html :

...
@if(user.isLoggedIn()) {
  @loggedInHeader()
} else {
  @controllers.Application.loginFormHeader()
}
...
views/loginFormHeader.scala.html :

@(form: Form)
...
如果用户已登录,则只需呈现另一个模板(本例中为loggedInHeader.scala.html),否则在控制器上调用另一个方法(但它可以在任何类型的类上):

此方法构造表单并使用如下模板进行渲染:

views/home.scala.html :

...
@if(user.isLoggedIn()) {
  @loggedInHeader()
} else {
  @controllers.Application.loginFormHeader()
}
...
views/loginFormHeader.scala.html :

@(form: Form)
...

您可以从所需的任何模板(主布局模板中的事件)调用
@controllers.Application.loginFormHeader()
方法,无需在其他任何地方生成表单对象。

谢谢。这个解决方案对我很有效。但是,在视图中调用控制器操作是一种良好的实践吗?事实上,它不是控制器操作(操作返回
结果
,并在routes文件中声明,这里我们返回
Html
)。可以将此方法放在不是控制器的类中。就我个人而言,我喜欢称这种东西为“组件”(我在symfony1.x:中经常使用这种模式)。创建一个专用的
组件
类是一个好主意,您将在其中放置此类代码以将其与实际控制器隔离。