Play Framework 2.1模板上的动态路由

时间:2013-04-07 16:47:14

标签: playframework routes playframework-2.0 scala-template

以Java计算机数据库样本作为Play的起点! 2.1我正在为大约20个模型开发一个CRUD管理员后端。我面临的问题是一遍又一遍地在模板级重复相同的功能。

我试图将链接功能重构为:

@****************************************
* Helper generating navigation links    *
****************************************@
@link(newPage:Int, newSortBy:String) = @{
    // Generate the link
    controllers.admin.routes.Model.index(newPage, "id", newSortBy)
}

类似

@(controller: Any, newPage: Int, newSortBy: String)
any.index(newPage, "id", newSortBy)

由于反向路由器不从任何特定类继承,因此我不能以通用方式进行。以前的代码不起作用,因为我没有进行类型转换(我猜因为编译器错误是“值索引不是Any的成员”)

有什么办法可以在运行时获取已定义路由的列表吗?如果它在Scala模板或Java端,无关紧要,这样我就可以传递控制器名称并获得正确的反向路由器来创建URL。

如果不可能,那么重构所有在模板上重复的代码的正确方法是什么,特别是那些依赖于ReverseRouters的代码。

1 个答案:

答案 0 :(得分:4)

我还没有找到一种方法来动态获取路由器和反向路由器的列表,但我找到了一种方法来限制样板代码的数量,并能够将模板函数重构为自己的文件,代码更易于管理。

我发现Scala不是另一种说Java的方式!具体来说,您可以将函数作为参数传递给函数(http://oldfashionedsoftware.com/2008/08/23/fun-with-scala-functions/),这样您就可以传递一段代码从主模板(DI类型)的子模板上执行。

在我发布的示例中,问题是将反向控制器从主模板传递给子模板,但“反向控制器”不会扩展任何特定对象。样本中的代码是:

template.scala.html

...
...
@****************************************
* Helper generating navigation links    *
****************************************@
@link(newPage:Int, newSortBy:String) = @{
    // Generate the link
    controllers.admin.routes.MyController.index(newPage, "id", "asc")
}
...
...
@**********************************
* Helper generating table headers *
***********************************@
@header(key:String, title:String) = {
    <th class="">
        <a href="@link(0, key)">@title</a>
    </th>
}
...
...

要将header函数重构为自己的模板,我必须能够调用link函数。由于反向控制器在link函数中被硬编码,因此使用重构文件中的包含将无法工作。解决方案是将header函数提取到子模板,并将模板的参数定义为函数:

视图/ utils的/ header.scala.html

@(key: String, title:String, link: (Int) => Html)
    <th class="@key">
        <a href="@link(0)">@title</a>
    </th>

现在在模板中:

视图/管理/ template.scala.html

...
@import utils._
...
@link(newPage:Int) = {
    @controllers.admin.routes.MyController.index(newPage, "id", "asc")
}
...
@header("key", "title", link _)
...

现在,我只需要为每个主模板定义link函数,并将其作为参数传递给任何需要它的子模板。不完全清洁但减少了很多锅炉板并简化了模板更换。

希望它能帮助别人。更好的解决方案?