#java #scala #templates #generics #playframework-2.2
#java #scala #шаблоны #общие #playframework-2.2
Вопрос:
У меня есть несколько отсортированных карт, с указанием времени и значением некоторого типа. Для иллюстрации рассмотрим, что у меня есть 3 карты (на Java):
SortedMap<OffsetDateTime, Foo> foo;
SortedMap<OffsetDateTime, Boo> bar;
SortedMap<OffsetDateTime, Baz> baz;
Я хочу написать общий шаблон воспроизведения, который принимает карту и функцию визуализации и выводит каждую пару.
В шаблоне я могу определить локальную функцию со следующей сигнатурой:
@renderTrace[T <: Any](trace: ImmutableSortedMap[OffsetDateTime, Option[T]], renderer: (T) => Html) = {
Однако я хотел бы использовать эту функцию в нескольких шаблонах, поэтому я не хочу определять ее локально. Скорее, я надеялся определить его как собственный шаблон (in RenderTrace.scala.html
).
К сожалению, я, похоже, не могу указать конструкцию типа [T <: Any]
в подписи шаблона.
Как я могу определить повторно используемую типизированную функцию?
Комментарии:
1. определите его во внешнем модуле и выполните
@import <yourmodule>
в шаблоне?2. Извините @Ashalynd, я не следую вашему предложению. Чтобы прояснить мою цель: поскольку сигнатура шаблона не является обычной сигнатурой метода Scala (в отличие от локальных функций, которые в значительной степени являются), я не нашел способ включить
[T <: Any]
.3. Здесь я столкнулся с той же проблемой — пытался написать несколько общих шаблонов, используя scala только для «помощников» и в самих шаблонах. Итак, какое решение вы выбрали в итоге?
4. @sandman: я использовал ответ ниже.
Ответ №1:
Чтобы конкретизировать предложение @Ashalynd, компилятор шаблонов, похоже, недостаточно умен для обработки параметров типа. Иногда вы можете использовать символ подчеркивания в качестве параметра типа (только если вам все равно, какой тип), но это не один из тех случаев.
Шаблон воспроизведения (теперь называемый twirl) — это, по сути, просто функция, которая выдает результат типа play.twirl.api.Html
(или play.api.templates.Html
для Play 2.2). Необходимо обойти компилятор шаблонов, поэтому определите вспомогательный пакет, содержащий вашу функцию:
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(...)}
Комментарии:
1. Правильно. Это то, чего я боялся. К сожалению, для меня мои контроллеры находятся на Java, поэтому мой помощник может быть еще более неприглядным. Или я могу также писать объекты Scala даже в приложении Play на основе Java? (Я проведу расследование, но знаете ли вы?)
2. Вы можете смешивать объекты Scala, поскольку обе версии Scala / Java в любом случае компилируются sbt через play / activator.