Play 2.4:Form:找不到参数消息的隐含值:play.api.i18n.Messages

arj*_*ads 44 forms scala playframework playframework-2.4

我是Play框架的新手并尝试在我的本地机器中模仿helloworld示例,但是我遇到了一个错误:

在此输入图像描述

路线:

# Home page
GET        /                    controllers.Application.index

# Hello action
GET        /hello               controllers.Application.sayHello


# Map static resources from the /public folder to the /assets URL path
GET        /assets/*file        controllers.Assets.versioned(path="/public", file: Asset)
Run Code Online (Sandbox Code Playgroud)

控制器:

package controllers

import play.api.mvc._
import play.api.data._
import play.api.data.Forms._

import views._

class Application extends Controller {

  val helloForm = Form(
    tuple(
      "name" -> nonEmptyText,
      "repeat" -> number(min = 1, max = 100),
      "color" -> optional(text)
    )
  )

  def index = Action {
    Ok(html.index(helloForm))
  }

  def sayHello = Action { implicit request =>
      helloForm.bindFromRequest.fold(
      formWithErrors => BadRequest(html.index(formWithErrors)),
      {case (name, repeat, color) => Ok(html.hello(name, repeat.toInt, color))}
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

视图:

@(helloForm: Form[(String,Int,Option[String])])

@import helper._

@main(title = "The 'helloworld' application") { 
    <h1>Configure your 'Hello world':</h1> 
    @form(action = routes.Application.sayHello, args = 'id -> "helloform") {
        @inputText(
            field = helloForm("name"),
            args = '_label -> "What's your name?", 'placeholder -> "World"
        )

        @inputText(
            field = helloForm("repeat"),
            args = '_label -> "How many times?", 'size -> 3, 'placeholder -> 10
        ) 
        @select(
            field = helloForm("color"),
            options = options(
                "" -> "Default",
                "red" -> "Red",
                "green" -> "Green",
                "blue" -> "Blue"
            ),
            args = '_label -> "Choose a color"
        ) 
        <p class="buttons">
            <input type="submit" id="submit">
        <p> 
    } 
}
Run Code Online (Sandbox Code Playgroud)

我安装了Play 2.4并使用IntelliJ Idea 14通过激活器模板创建了项目.

ps_*_*ttf 65

implicit messages向视图添加参数后,您只需添加以下导入并使用旧的控制器类甚至对象,而无需任何其他更改:

import play.api.Play.current
import play.api.i18n.Messages.Implicits._
Run Code Online (Sandbox Code Playgroud)

  • 值得一提的是,这种方法将被取消,因为删除了play的全局状态.请参阅[迁移指南/依赖关系注入](https://www.playframework.com/documentation/2.4.x/Migration24#Dependency-Injection). (7认同)
  • 为什么这不是文档推荐的方法?这似乎比扩展`I18Support`并注入`MessagesApi`简单得多 (3认同)
  • 我想Play Framework开发人员试图推广更加可定制的新方法.导入`play.api.i18n.Messages.Implicits._`值会在Play消息提供程序中引入硬编码依赖项.依赖性没有参数化,这在某些情况下是不方便的,例如用于编写隔离单元测试.因此,使用具有参数化依赖性的控制器类的方法更加清晰.然而,在我的应用程序中,通常使用具有硬编码依赖关系的oldschool控制器*对象*就足够了.我更喜欢使用更简单的解决方案. (2认同)

Rom*_*man 44

使用视图表单助手(例如@inputText)要求您将隐式play.api.i18n.Messages参数传递给视图.您可以(implicit messages: Messages)在视图中添加到签名中.你的观点变成了这样:

@(helloForm: Form[(String,Int,Option[String])])(implicit messages: Messages)

@import helper._

@main(title = "The 'helloworld' application") { 
  <h1>Configure your 'Hello world':</h1> 
  ...
Run Code Online (Sandbox Code Playgroud)

然后在您的应用程序控制器中,您必须在范围中隐式提供此参数.最简单的方法是实现游戏的I18nSupport特性.

在您的示例中,这将如下所示:

package controllers

import play.api.mvc._
import play.api.data._
import play.api.data.Forms._
import javax.inject.Inject
import play.api.i18n.I18nSupport
import play.api.i18n.MessagesApi

import views._

class Application @Inject()(val messagesApi: MessagesApi) extends Controller with I18nSupport {

  val helloForm = Form(
    tuple(
      "name" -> nonEmptyText,
      "repeat" -> number(min = 1, max = 100),
      "color" -> optional(text)
    )
  )

  def index = Action {
    Ok(html.index(helloForm))
  }

  def sayHello = Action { implicit request =>
    helloForm.bindFromRequest.fold(
      formWithErrors => BadRequest(html.index(formWithErrors)),
      {case (name, repeat, color) => Ok(html.hello(name, repeat.toInt, color))}
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

在您的控制器中,您当然可以使用自己的实现MessagesApi.因为游戏知道开箱即用,MessagesApi你可以简单地注释你的控制器,@Inject然后让你为你做的工作.

正如Matthias Braun所说,你也必须设定

routesGenerator := InjectedRoutesGenerator
Run Code Online (Sandbox Code Playgroud)

在你的 build.sbt

有关I18n的更多信息,请参见https://www.playframework.com/documentation/2.4.x/ScalaI18N.

  • @MichaelA.将`val messages:MessagesApi`更改为`val messagesApi:MessagesApi`.这将自动覆盖`I18nSupport`中定义的`abstract def messagesApi`. (3认同)
  • 我已经有了:`class AppController @Inject()(val messages:MessagesApi)使用I18nSupport {...}`扩展Controller.如果我正确地理解了答案,那就足够了 - 但我仍然得到了这个信息. (2认同)
  • 卫生署.现在工作 - 一千谢谢.可以花费数小时盯着......的那种错误之一...... (2认同)
  • 为了实现这一点,我不得不将`routesGenerator:= InjectedRoutesGenerator`添加到我的`build.sbt`并使用`@`:GET/hello @ controllers.Application.sayHello`将路由添加到我的控制器前面. (2认同)
  • 我还必须添加`import play.api.i18n.I18nSupport`和`import play.api.i18n.MessagesApi`来使其工作. (2认同)