【问题标题】:Passing common state in Play Framework在 Play Framework 中传递公共状态
【发布时间】:2013-06-09 17:25:07
【问题描述】:

关于将通用状态传递给模板,我对理解 Play 框架有一个或多或少的一般性问题。这是一个被广泛讨论的话题,比如这里:http://jazzy.id.au/default/2012/10/26/passing_common_state_to_templates_in_play_framework.html 但我仍然不确定最佳做法是什么。我熟悉基于脚本语言的 MVC 框架,如 CakePHP 或 Django,所以这个问题对我来说并不重要。 所以,基本上有两种可能:

  • 在模板中使用隐式变量,这仅适用于 Scala,您仍然必须在每个模板中声明该变量!?
  • 使用 Http.Context 类来存储数据,这对我来说更像是一种 hack,它不太适合传递大量数据。 (如有错误请指正)

对于这个问题,我有两个重要的用例。第一个是让登录的用户对象随处可用。这是使用 Http.Context 很容易解决的问题。第二个对我来说更难。我有一个标题,它要么显示登录表单,要么显示一些用户特定的选项。因此,我在模板中有一个 if 条件,检查用户是否登录。但是当我显示登录表单时,我需要在控制器中生成表单对象。因此,我必须在每个控制器中生成该对象并将其传递给每个模板,尽管我只在没有用户登录时才需要它。我确定 Play 框架的制造商是否是这样的意思。

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

【问题讨论】:

    标签: playframework


    【解决方案1】:

    为了显示你的表单,你可以调用一个方法来创建表单并渲染一个模板,而不是仅仅调用另一个模板。

    例如,您可以有一个模板来显示用户信息或这样的表单:

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

    如果用户已经登录,你只需渲染另一个模板(在这种情况下为 loggedInHeader.scala.html),否则你在控制器上调用另一个方法(但它可以在任何类型的类上):

    app/controllers/Application.java :
    
    class Application extends Controller {
      ...
      public static Html loginFormHeader() {
        Form form = Form.form(...);
        return views.html.loginFormHeader.render(form);
      }
    }
    

    这个方法构造表单并使用这样的模板渲染它:

    views/loginFormHeader.scala.html :
    
    @(form: Form)
    ...
    

    您可以从任何您想要的模板(来自主布局模板的事件)调用@controllers.Application.loginFormHeader() 方法,而无需在其他任何地方构建 Form 对象。

    【讨论】:

    • 谢谢。该解决方案对我来说非常有效。但是在 Play 中调用视图中的控制器操作是一种好习惯吗?
    • 实际上它不是一个控制器动作(一个动作返回一个Result并在路由文件中声明,这里我们返回一个Html)。您可以将此方法放在不是控制器的类中。就个人而言,我喜欢将这种东西称为“组件”(我在 Symfony 1.x 中经常使用这种模式:symfony.com/legacy/doc/gentle-introduction/1_4/en/…)。创建一个专用的Component 类可能是个好主意,您将在其中放置此类代码以将其与真实控制器隔离。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    • 2013-05-11
    • 1970-01-01
    相关资源
    最近更新 更多