Работа с передачей неявного параметра каждому отдельному шаблону

Я немного работаю с шаблонами PlayFramework, но столкнулся с проблемой. Мы используем помощники игры, для которых требуется Messages (импортировано из play.api.i18n). Все было в порядке, пока наш дизайнер не захотел иметь форму входа в модальную форму... Поскольку она будет добавлена ​​к каждому отдельному шаблону, нам нужно будет везде добавлять этот параметр сообщений - что некрасиво, ИМХО.

Есть ли способ обойти это? Передача его везде будет означать, что я должен Inject() его везде, даже если его нужно передать только для закрытия проверки типов.

Пример страницы:

@(project: model.Project)(implicit request: Request[AnyContent], messages: Messages)
@main(project.name){
    <h1>@project.name</h1>
    <ul>
    @for(member <- project.members) {
        <li><a href="@routes.UsersController.view(member)">@member</a></li>
    }
    </ul>
}{}

Фрагмент основного шаблона:

@(title: String)(content: Html)(additionalImport: Any)(implicit req: Request[AnyContent], messages: Messages)

<!DOCTYPE html>

<html lang="en">
    <head>

    </head>
    <body>
        @* this call actually needs that param. *@ 
        @header.navbar()
        <div class="container">
            @req.flash.get("error").map { error =>
                <div class="flash-error">@error</div>
            }
            @content

        </div>
    </body>
</html>

Форма:

@import model.UserLoginData
@(loginForm: Form[UserLoginData])(implicit req: Request[AnyContent], messages: Messages)
    @helper.form(action = routes.AuthenticationController.login()) {

        @loginForm.globalErrors.map { error =>
            <div class="error">@error.message</div>
        }

        @helper.inputText(loginForm("login"))

        @helper.inputPassword(loginForm("password"))

        <input type="submit" value="Zaloguj"/>
    }
    <a href="@routes.AuthenticationController.recoverForm()">Zapomniałem hasła</a>

person Haito    schedule 11.02.2016    source источник


Ответы (1)


Здесь я вижу два обходных пути. К сожалению, я не могу проверить их сейчас, но я думаю, что они оба будут работать.

  1. Избавьтесь от параметра messages из шаблона формы. Используйте Play.current.injector.instanceOf[MessagesApi], чтобы получить реализацию MessagesApi прямо внутри шаблона (вот вопрос о доступе к инжектору без аннотации @Inject). Затем вы можете вызвать метод preferred(Http.RequestHeader request):Messages, чтобы получить экземпляр Messages, а затем вам нужно явно передать это вспомогательному методу.
  2. Если вы просто хотите избавиться от инъекций и не возражаете против передачи неявного параметра messages в каждый отдельный шаблон, вы можете реализовать свою собственную версию трейта I18nSupport. Здесь я имею в виду, что вы обычно пишете контроллер следующим образом: class SomeController @Inject()(val messagesApi: MessagesApi) extends Controller with I18nSupport. Значение messagesApi переопределяет то же значение признака I18nSupport. Вы можете расширить этот трейт своим собственным трейтом MyI18Support и внедрить в него MessagesApi (UPD: вы можете либо @Iinject, либо использовать Play.current.injector). Тогда вам останется только написать контроллер следующим образом: class SomeController extends Controller with MyI18nSupport.
person Ilya Posov    schedule 14.02.2016
comment
Я понял, что что-то не так с обоими этими решениями. Может быть, проблема будет в производительности или в тестировании, и я не имею опыта в DI, чтобы сказать наверняка. - person Ilya Posov; 14.02.2016
comment
Я их обязательно протестирую. - person Haito; 14.02.2016
comment
Конечно, для такого долгого времени оценки. Мы реализовали первое решение. И это работает. Большое тебе спасибо. - person Haito; 27.02.2016