Scala 如何在播放视图中处理隐式传递的未来

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

在我的特殊情况下,我有一个在所有页面上呈现的菜单。菜单内容使用slick从数据库加载,并隐式传递到视图。整个事情看起来是这样的:

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隐式发挥作用。非常感谢!今天我学到了很多东西。请投我的赞成票。