我是Play Framework的新手,仍然试图用新的Scala模板引擎来解决一些问题。
假设我有以下包结构:
app/
app/controllers/Items.scala
app/models/Item.scala
app/views/layouts/page.scala.html
app/views/item/show.scala.html
app/views/item/details.scala.html //partial
这是我的项目/节目模板:
@(item: Item, form: Form[Item])(implicit flash: Flash)
@layout.page() {
@*want to include details partial, wont work due to item param*@
@item.details(item)
}
由于包含另一个模板(例如包括上面的项目/详细信息)与访问模板参数(例如上面的项目)的语法完全相同,显然这个现有的命名约定在没有变化的情况下将无法工作。
我知道我可以将我的“app.views.item”包重命名为“app.views.items”,并依赖单数/复数形式来区分视图和param名称,但这似乎不是很好直截了当的解决方案另外,如果我真的希望参数名称与视图包相同呢?
我的一个想法是用额外的顶级包装前置我的所有观点:
app/views/views/item/details.scala.html
因此include语法将是@ views.item.details(),但这显然是一个黑客攻击。
避免此问题的好方法是什么?如何更好地组织代码以避免此类命名冲突?
大多数其他模板引擎使用“include”或“render”等操作来指定部分包含。我不是故意冒犯任何人,但Play Scala模板引擎的语法是如此简洁,它实际上决定了代码的组织?
答案 0 :(得分:1)
3个解决方案:
部分模板的Typpicaly应该使用tags
,如in the docs所述,其中app/views/tags
文件夹是基础:
档案:app/views/tags/product.scala.html
(父视图中不需要初始导入完整语法将允许您避免名称冲突:@tags.packageName.tagName()
):
<div id="container">
@tags.product(item)
</div>
当然,在您的情况下,您也可以使用基础文件夹中的包
档案:app/views/tags/item/product.scala.html
<div id="container">
@tags.item.product(item)
</div>
我很确定这会解决你的问题。
为了避免在不更改包名称的情况下发生冲突,您只需在视图中重命名item
,我也建议您不要使用{[1}}名称作为Form [T],因为它可能与帮助者冲突:
form
如果在传递给定@(existingItem: Item, existingItemForm: Form[Item])(implicit flash: Flash)
@layout.page() {
@item.details(existingItem)
}
对象的视图之前填充Form[Item]
,则不需要同时传递两者,因为大多数情况下您可以从表单中获取数据:
Item
当然,在您的product.scala.html中,您需要将@(itemForm: Form[Item])(implicit flash: Flash)
@layout.page() {
<div>Name of item is: @itemForm("name").value (this is a replacemnet for @@existingItem.name </div>
@item.details(itemForm)
}
参数更改为@(item: Item)