Параметр и просмотр коллизий имен в шаблонах Play/Scala

Я новичок в 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» и полагаться на формы единственного/множественного числа, чтобы отличать представление от имени параметра, но это не кажется очень простым решением. Кроме того, что, если я действительно хочу, чтобы имя параметра совпадало с именем пакета представления?

Одна идея, которую я имею, состоит в том, чтобы добавить ко всем моим представлениям дополнительный пакет верхнего уровня:

 app/views/views/item/details.scala.html

Таким образом, синтаксис включения будет @views.item.details(), но опять же это, очевидно, хак.

Какой хороший способ избежать этой проблемы? Как я могу лучше организовать свой код, чтобы избежать таких конфликтов имен?

Большинство других шаблонизаторов используют такие операции, как «include» или «render», чтобы указать частичное включение. Я не хочу никого здесь обидеть, но настолько ли лаконичен синтаксис шаблонизатора Play Scala, что он фактически диктует организацию кода?


person kgx    schedule 20.10.2012    source источник
comment
Возможно, используя полное квалифицированное имя: @views.item.details(item)   -  person ndeverge    schedule 20.10.2012
comment
Также я заметил аналогичную проблему с именами классов Controller и Model. В различных примерах приложений я вижу имена моделей, такие как app.models.Item, и имена контроллеров, такие как app.controllers.Items. С импортом на уровне пакета теперь новый разработчик должен выяснить, что Item — это модель, а Items — это контроллер. Это работает, опять же, это кратко, но я обеспокоен возможностью путаницы/плохой читабельности.   -  person kgx    schedule 20.10.2012
comment
@nico_ekito, полное имя представления мне не подходит. Я получаю ошибку компиляции. Я пробовал @app.views.item.details(item), а также @views.item.details(item). Какие-либо предложения?   -  person kgx    schedule 20.10.2012
comment
Правильное полное имя, которое работает: @views.html.item.details(item).   -  person kgx    schedule 20.10.2012
comment
да, я всегда забываю .html ;-)   -  person ndeverge    schedule 20.10.2012


Ответы (1)


3 решения:

Первый

Обычно для частичных шаблонов следует использовать tags, как описано в документации, где 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 в своем представлении, также я рекомендую не использовать имя form для формы [T], так как это может конфликтовать с помощниками:

@(existingItem: Item, existingItemForm: Form[Item])(implicit flash: Flash)
@layout.page() {
    @item.details(existingItem)
}

Третий

Если вы заполните свой Form[Item] перед переходом к представлению с данным объектом Item, вам не нужно передавать оба, так как, скорее всего, вы можете получить данные из формы:

@(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)
}

Конечно, в вашем product.scala.html вам нужно изменить параметр @(item: Item) на @(itemForm: Form[Item]).

person biesior    schedule 20.10.2012
comment
Хороший звонок! Мне никогда не приходило в голову, что, поскольку все является функцией, я могу просто считать включение тегом. Я собирался пойти с таким соглашением, как app.views.item.includes, но мне больше нравится подход app.views.tags.item. - person kgx; 20.10.2012
comment
Мне не нравится (2), но я вижу, что вы не используете форму имени параметра... itemForm кажется лучшим вызовом. (3) работает, но предполагая, что мне также нужен экземпляр Item, он не решает мою первоначальную проблему. Я уже начал рефакторинг кода для использования подхода (1). - person kgx; 20.10.2012