Play Framework 模板中的有界通用参数
Bounded generic parameters in Play Framework template
如何在 Play Framework 2.3 Java 项目的 Scala 模板中使用有界泛型参数?
我目前有类似的东西:
@(entities: List[_ <: Entity], currentEntity: Entity)
<ul>
@for(entity <- entities) {
@if(currentEntity.equals(entity)) {
<li><strong>@entity</strong></li>
} else {
<li>@entity</li>
}
}
</ul>
但是,我可以在 entities
和 currentEntity
中用不同类型的实体调用它 - 这不太好。我想做类似的事情:
@[T <: Entity](entities: List[T], currentEntity: T)
...
但这给了我 Invalid '@' symbol
作为编译错误。
正如@m-z 指出的那样,它还不受支持(目前)。但是你可能能够通过首先将你的参数编组到一个 View 对象来获得你想要的类型安全(以另一个 类 家族为代价):
case class HighlightedListView[E <: Entity](entities:List[E], currentEntity:E)
现在在您的控制器中加载一个新的 HighlightedListView
实例,而不是直接将参数提供给模板:
def foo = Action {
...
// Assuming some SubEntity exists, the compiler will enforce the typing:
val hlv = HighlightedListView[SubEntity](entities, currentEntity)
Ok(html.mytemplate(hlv))
}
如评论所述,如果您的类型不一致,编译器将会呕吐。然后模板可以非常宽松地使用类型,因为我们知道我们是安全的:
@(hlv:HighlightedListView[_])
<ul>
@for(entity <- hlv.entities) {
@if(hlv.currentEntity.equals(entity)) {
<li><strong>@entity</strong></li>
} else {
<li>@entity</li>
}
}
</ul>
您甚至可以利用新的 View
对象来添加辅助方法,这可以使模板更易于阅读,并促进单元测试:
case class HighlightedListView[E <: Entity](entities:List[E], currentEntity:E) {
def shouldHighlight(e:Any):Boolean = currentEntity.equals(e)
}
导致:
@if(hlv.shouldHighlight(entity)) {
<li><strong>@entity</strong></li>
} else {
<li>@entity</li>
}
如何在 Play Framework 2.3 Java 项目的 Scala 模板中使用有界泛型参数?
我目前有类似的东西:
@(entities: List[_ <: Entity], currentEntity: Entity)
<ul>
@for(entity <- entities) {
@if(currentEntity.equals(entity)) {
<li><strong>@entity</strong></li>
} else {
<li>@entity</li>
}
}
</ul>
但是,我可以在 entities
和 currentEntity
中用不同类型的实体调用它 - 这不太好。我想做类似的事情:
@[T <: Entity](entities: List[T], currentEntity: T)
...
但这给了我 Invalid '@' symbol
作为编译错误。
正如@m-z 指出的那样,它还不受支持(目前)。但是你可能能够通过首先将你的参数编组到一个 View 对象来获得你想要的类型安全(以另一个 类 家族为代价):
case class HighlightedListView[E <: Entity](entities:List[E], currentEntity:E)
现在在您的控制器中加载一个新的 HighlightedListView
实例,而不是直接将参数提供给模板:
def foo = Action {
...
// Assuming some SubEntity exists, the compiler will enforce the typing:
val hlv = HighlightedListView[SubEntity](entities, currentEntity)
Ok(html.mytemplate(hlv))
}
如评论所述,如果您的类型不一致,编译器将会呕吐。然后模板可以非常宽松地使用类型,因为我们知道我们是安全的:
@(hlv:HighlightedListView[_])
<ul>
@for(entity <- hlv.entities) {
@if(hlv.currentEntity.equals(entity)) {
<li><strong>@entity</strong></li>
} else {
<li>@entity</li>
}
}
</ul>
您甚至可以利用新的 View
对象来添加辅助方法,这可以使模板更易于阅读,并促进单元测试:
case class HighlightedListView[E <: Entity](entities:List[E], currentEntity:E) {
def shouldHighlight(e:Any):Boolean = currentEntity.equals(e)
}
导致:
@if(hlv.shouldHighlight(entity)) {
<li><strong>@entity</strong></li>
} else {
<li>@entity</li>
}