Play/Scala 中的隐式参数和组合视图
Posted
技术标签:
【中文标题】Play/Scala 中的隐式参数和组合视图【英文标题】:Implicit parameters and combined views in Play/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>
main.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 调用 main,我希望两者都访问 messages。
编译器在 index 内给了我“could not find implicit value for parameter messages: play.api.i18n.Messages”,但如果我删除了隐式参数声明从 main 然后 index 工作正常并收到消息。似乎编译器告诉我它不知道如何将隐式参数向下传递。
在尝试解决方法之前,我想了解为什么这不起作用。
【问题讨论】:
【参考方案1】:在 Play 2.4 中,您需要在控制器中注入 MessageAPI 并在您的操作中调用首选菜单来创建消息。 如果您将其定义为隐含在您的操作中。然后一切都会好起来的。
【讨论】:
嗨 Soroosh,正如我在我的问题中提到的那样,我通过完全按照您所说的进行部分工作。这是我的控制器:class Application @Inject() (val messagesApi: MessagesApi) extends Controller with I18nSupport def index = Action implicit request => 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>
main.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 =>
隐式参数。还要在你的控制器中包含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"))
【讨论】:
以上是关于Play/Scala 中的隐式参数和组合视图的主要内容,如果未能解决你的问题,请参考以下文章