【问题标题】:Implicit parameters and combined views in Play/ScalaPlay/Scala 中的隐式参数和组合视图
【发布时间】:2015-06-12 19:15:54
【问题描述】:

这个问题建立在我发现的一个案例 here

index.scala.html

@(text: String)(implicit messages: Messages)

@main("Fancy title") {
  <h1>@messages("header.index")</h1>
  <div>@text</div>
}

ma​​in.scala.html

@(title: String)(content: Html)(implicit messages: Messages)
  <html>
  <head>
    <title>@title</title>
  </head>
  <body>
    <h1>@messages("header.main")</h1>
    @content
  <body>
</html>

在此示例中,我有 index 调用 ma​​in,我希望两者都访问 messages

编译器在 index 内给了我“could not find implicit value for parameter messages: play.api.i18n.Messages”,但如果我删除了隐式参数声明从 ma​​in 然后 index 工作正常并收到消息。似乎编译器告诉我它不知道如何将隐式参数向下传递。

在尝试解决方法之前,我想了解为什么这不起作用。

【问题讨论】:

    标签: scala playframework-2.4


    【解决方案1】:

    在 Play 2.4 中,您需要在控制器中注入 MessageAPI 并在您的操作中调用首选菜单来创建消息。 如果您将其定义为隐含在您的操作中。然后一切都会好起来的。

    【讨论】:

    • 嗨 Soroosh,正如我在我的问题中提到的那样,我通过完全按照您所说的进行部分工作。这是我的控制器:
    • class Application @Inject() (val messagesApi: MessagesApi) extends Controller with I18nSupport { def index = Action { implicit request =&gt; Ok(views.html.index("blah bla blah")) } 当我尝试使用控制器调用的 index 调用的 main 中的消息时,就会出现问题。我正在寻找一种干净的方法来为所有嵌套视图注入一些全局数据(在这种情况下是消息)
    • 在您的操作中调用首选菜单以创建消息究竟是什么意思?
    【解决方案2】:

    首先让我添加控制器的代码,以使我的原始示例更清晰。

    Application.scala(原始)

    class Application @Inject() (val messagesApi: MessagesApi) extends Controller with I18nSupport { 
       def index = Action { implicit request => 
          Ok(views.html.index("blah bla blah")) 
    }
    

    在更详细地研究了 Play Framework 文档 (here) 之后,我了解了一种从模板中访问消息的替代方法(这可能也更简洁)。

    Application.scala(新)

    class Application extends Controller { 
       def index = Action {
          Ok(views.html.index("blah bla blah"))
       }
    }
    

    index.scala.html(新)

    @import play.i18n._
    @(text: String)
    @main("Fancy title") {
      <h1>@Messages.get("header.index")</h1>
      <div>@text</div>
    }
    

    ma​​in.scala.html(新)

    @import play.i18n._
    @(title: String)(content: Html)
      <html>
        <head>
          <title>@title</title>
        </head>
        <body>
          <h1>@Messages.get("header.main")</h1>
          @content
        <body>
      </html>
    

    控制器不再需要所有额外的基础设施。

    视图需要添加导入语句,但丢失了隐式参数声明。

    使用@Messages.get("xyz") 而不是@Messages("xyz") 访问消息。


    目前这种方法适合我的需要。

    【讨论】:

    • 这个解决方案比较干净,但是,当你想改变一个语言时,你怎么办?
    【解决方案3】:

    Play 框架会将您的请求隐式转换为 MessagesApi 以供您查看。但是,您确实需要在控制器方法中包含 request =&gt; 隐式参数。还要在你的控制器中包含I18nSupport trait。

    import play.api.i18n.{MessagesApi, I18nSupport}
    
    @Singleton
    class HomeController @Inject() (cc: ControllerComponents)
    extends AbstractController(cc) with I18nSupport {
    
      def showIndex = Action { implicit request =>
        Ok(views.html.index("All the langs"))
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-20
      • 2012-04-27
      • 1970-01-01
      相关资源
      最近更新 更多