Play / Scala模板中的参数和视图命名冲突

时间:2012-10-20 14:08:54

标签: scala playframework playframework-2.0

我是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模板引擎的语法是如此简洁,它实际上决定了代码的组织?

1 个答案:

答案 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)