定义和引用Play模板签名中绑定的泛型类型

时间:2014-06-23 06:06:49

标签: java scala templates generics playframework-2.2

我有许多有序的地图,按时间键入,值某种类型。为了说明,我认为我有3张地图(用Java表示):

SortedMap<OffsetDateTime, Foo> foo;
SortedMap<OffsetDateTime, Boo> bar;
SortedMap<OffsetDateTime, Baz> baz;

我希望编写一个接受地图和渲染器功能的通用Play模板,并输出每对。

模板中,我可以使用以下签名定义 local 函数:

@renderTrace[T <: Any](trace: ImmutableSortedMap[OffsetDateTime, Option[T]], renderer: (T) => Html) = {

但是,我想在多个模板中使用此功能,所以我不想在本地定义它。相反,我曾希望将其定义为自己的模板(在RenderTrace.scala.html中)。

不幸的是,我似乎无法在模板签名中指定类型构造[T <: Any]

如何定义可重复使用的通用类型函数?

1 个答案:

答案 0 :(得分:4)

为了充实@ Ashalynd的建议,模板编译器似乎不够智能来处理类型参数。有时您可以使用下划线作为类型参数(仅当您不关心类型是什么时),但这不是其中之一。

Play(现在称为twirl)模板本质上只是一个产生类型play.twirl.api.Html(或Play {2.2的play.api.templates.Html)结果的函数。模板编译器需要解决,所以定义一个包含你的函数的帮助包:

package viewhelpers

import play.twirl.api.Html // play.api.templates.Html for 2.2

object ViewExtension {

    def renderTrace[T <: Any](trace: ImmutableSortedMap[OffsetDateTime, Option[T]], renderer: (T) => Html): Html = ...

}

renderTrace的实现可能看起来不像在视图模板中那样好,但至少它现在可以正常工作。

然后在视图中:

@(someParams: ....)
@import viewhelpers.ViewExtension

@{ViewExtension.renderTrace(...)}