以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的代码。
答案 0 :(得分:4)
我还没有找到一种方法来动态获取路由器和反向路由器的列表,但我找到了一种方法来限制样板代码的数量,并能够将模板函数重构为自己的文件,代码更易于管理。
我发现Scala不是另一种说Java的方式!具体来说,您可以将函数作为参数传递给函数(http://oldfashionedsoftware.com/2008/08/23/fun-with-scala-functions/),这样您就可以传递一段代码从主模板(DI类型)的子模板上执行。
在我发布的示例中,问题是将反向控制器从主模板传递给子模板,但“反向控制器”不会扩展任何特定对象。样本中的代码是:
...
...
@****************************************
* 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
函数提取到子模板,并将模板的参数定义为函数:
@(key: String, title:String, link: (Int) => Html)
<th class="@key">
<a href="@link(0)">@title</a>
</th>
现在在模板中:
...
@import utils._
...
@link(newPage:Int) = {
@controllers.admin.routes.MyController.index(newPage, "id", "asc")
}
...
@header("key", "title", link _)
...
现在,我只需要为每个主模板定义link
函数,并将其作为参数传递给任何需要它的子模板。不完全清洁但减少了很多锅炉板并简化了模板更换。
希望它能帮助别人。更好的解决方案?