Play框架支持"snippets"吗?

8
如果我想在多个页面上拥有一个通用的UI元素,例如菜单,那么推荐的做法是什么?它将包含模板代码和后端控制器(类似于LiftWeb框架中的“片段”)。我知道Play有一个菜单模块,但我更感兴趣的是如何在一般情况下实现这一点。
1个回答

11

在Play框架中,有两种方法可以将通用的视图代码包含进来。

你可以使用#{include}标签或#{extends}标签。

如其名所示,extends标签继承自父视图。在创建新应用时,Play设置的骨架代码默认使用该标签。它会继承main.html,你只需在其中添加代码即可。

include标签允许你在指定位置将一段常用的视图代码注入到你的模板中。这类似于php的include/require或jsp的include功能。

当你的模板代码还需要来自模型(通过控制器)的数据或逻辑时,问题就出现了。如果是这种情况,那么你就需要在控制器中使用@Before或@With注释,以确保每次都执行一段共用的控制器代码。你可以将任何数据添加到renderArgs列表中,以便在视图中使用它们。

使用renderArgs的一个简单示例:

@Before
private static void commonData() {
    // do your logic here
    renderArgs.put("menu", menu);
    renderArgs.put("selected", selectedMenuItem);
}

你放入renderArgs中的值(例如示例中的menu和selected)将会以与传递给render方法相同的方式可用。


谢谢 - 你能给我指一些使用renderArgs的示例代码吗? - sanity
@Codemwnci 我在我的renderArgs{}中得到了空/ null值。成功登录后,我将一个map存储在renderArgs中,并使用renderArgs.get(login_det').toString()在控制台上打印了所有值。当我在另一个控制器中使用相同的内容时,我得到的renderArgs是{}。这里可能有什么问题? - Arasu
这是否属于同一操作?您是否在@Before中使用renderArgs存储数据?请记住,renderArgs仅在请求的生命周期内存在,因此它将在下一个请求中丢失。还要记住,如果您从一个操作中调用另一个操作,它将强制进行HTTP重定向,这是另一个请求,因此renderArgs会被重置。 - Codemwnci
@Codemwnci 我在登录时和一个名为 <pre>@</pre>Before 的单独函数中设置了 a 中的值。 private static void commonData() { Map cacheMap = Cache.get("login_det",Map.class); if(cacheMap!=null) { renderArgs.put("login_det", cacheMap); System.out.println("commonData"+renderArgs.toString()); }} - Arasu
在我的 customersList 控制器函数中,我打印了 cache 和 renderArgs.toString()。Cache 仍然有值,但是 renderArgs 是 {}。 - Arasu
如果您在登录操作中设置值,则该值仅在该请求中有效。另一方面,缓存旨在允许项目在多个请求中存在。 - Codemwnci

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接