Scala 如何在播放视图中处理隐式传递的未来
在我的特殊情况下,我有一个在所有页面上呈现的菜单。菜单内容使用slick从数据库加载,并隐式传递到视图。整个事情看起来是这样的:Scala 如何在播放视图中处理隐式传递的未来,scala,playframework,playframework-2.0,slick,playframework-2.4,Scala,Playframework,Playframework 2.0,Slick,Playframework 2.4,在我的特殊情况下,我有一个在所有页面上呈现的菜单。菜单内容使用slick从数据库加载,并隐式传递到视图。整个事情看起来是这样的: class BlahController extends Controller with MenuDecoration { def index = Action.async { withMenuSimple { getContent.map { content => implicit menu => Ok(view
class BlahController extends Controller with MenuDecoration {
def index = Action.async {
withMenuSimple {
getContent.map { content => implicit menu =>
Ok(views.html.index(content))
}
}
}
}
def indexWithReq = Action.async { implicit request =>
withMenu { req =>
getContent.map { content => implicit menu =>
Ok(views.html.index(content))
}
}
}
控制器
class Application @Inject()(
implicit val menuContext: MenuContext
) extends Controller {
def index = Action.async {
val content: Future[Content] = getContent
content.map(c => Ok(views.html.index(c)))
}
}
MenuContext
class MenuContext {
val models: Future[List[SomeModel]] = getModelsFromDB
}
查看
@(content: Content)(implicit menuContext: MenuContext)
...
@menuContext.models // how to access my actual model and not the Future?
...
如何访问视图中的
列表[SomeModel]
?传递隐式参数时是否有一个Action.async
等价物?或者,对于(几乎)所有视图中都需要的内容,是否有更好的解决方案?让模板必须处理未来的问题肯定不是一个好主意
-因此,这个问题成为您评论中的一个问题-如何无阻碍地(?)从异步内容源获取内容,以及来自其他异步内容源的菜单项
对于,理解两个未来的实例可以达到以下目的:
def index = Action.async {
val fContent:Future[Content] = getContent
val fMenus:Future[List[SomeModel] = getModelsFromDB
for {
content <- fContent
menus <- fMenus
} yield(Ok(views.html.index(content)(menus))))
}
def index=Action.async{
val fContent:Future[Content]=getContent
val fMenus:Future[List[SomeModel]=getModelsFromDB
为了{
content好的,我在这里添加另一个答案,专门尝试将菜单注入到您的操作中
主要问题是您需要在正确的时间插入菜单,即:
- 当您准备好数据时(或至少在未来保存数据时)
- 当您知道要渲染哪个模板时
- 当您知道要返回的状态代码时
由于这些限制,我们不能使用or-它们假定控制器代码的内部块将生成一个完成的结果
因此,我们将定义一种可以混合到控制器中的特性:
trait MenuDecoration {
def withMenuSimple(body: Future[List[SomeModel] => Result]):Future[Result] = {
val fm = getModelsFromDB
val fb = body
for {
m <- fm
b <- fb
} yield(b(m))
}
}
为什么使用菜单来查看
?因为在某个时候,您可能需要检查请求
——因此我们有以下选择:
trait MenuDecoration {
...
def withMenu(body: RequestHeader => Future[List[SomeModel] => Result])(implicit request:RequestHeader):Future[Result] = {
val fm = fMenus
val fb = body(request)
for {
m <- fm
b <- fb
} yield(b(m))
}
}
未来的执行肯定是后端的任务,而不是模板的任务。您应该将实际的模型传递给视图。请原谅我的noobish问题,但我如何以非阻塞的方式执行?谢谢millhouse。隐式传递menuContext的目的是因为我想避免手动获取每个操作中的菜单项。menuContext
几乎在所有视图中都应该可用。理想情况下,我会在控制器中插入一个menuContext,让scala隐式发挥作用。非常感谢!今天我学到了很多东西。请投我的赞成票。