templates - 玩! Framework 2.0 - 循环遍历 scala 模板中的 map ?

标签 templates scala playframework playframework-2.0

我有一张代表目录的 map ,它包含 Chapter键和List[Section]值(value)观。现在我正在尝试在我的模板中循环遍历它,如下所示:

<dl>
@table_of_contents.foreach((e) => {
    <dt>
        @e._1.title
    </dt>
        for(section <- e._2){
        <dd>
            @section.title
        </dd>
        }
})
</dl>

我目前在 <dl> 中没有得到任何输出然而。

我添加了println(table_of_contents)模板顶部的声明,以确保 map 确实有数据并打印:

{models.Chapter@1=BeanList size[4] hasMoreRows[false] list[models.Section@1, models.Section@2, models.Section@3, models.Section@4], models.Chapter@2=BeanList size[0] hasMoreRows[false] list[]}

也许我需要使用命令式风格?

更新:

仍在研究这个...得到了这个变体来编译,但没有输出。

<dl>
@table_of_contents.foreach{case(a, b) => {
    <dt>
        @a.title
    </dt>
        @displaySections(b)
}}
</dl>

...

@displaySections(sections: List[Section]) = {
  @for(a_section <- sections) {
        <dd>@a_section.title</li>
  }
}

最佳答案

tl;博士

到目前为止给出的答案(评论中的 @wbarksdale@PlexQ@Daniel C. Sobral )足以解决此处描述的问题。

但是他们缺少关于为什么使用 foreach 的初始代码不起作用的真正解释。

它无法工作,因为 foreach 返回 Unit

游戏理念

让我快速说明/记忆一下模板的工作原理。

Play Framework 2 默认提供的 Scala 模板系统确实是基于 FP 概念构建的,因此它使用了大量不可变结构等等。

此外,这样的 Scala 模板(比如说 myTemplate.scala.html)将被编译成一个常规的 Scala 对象,它有一个 apply方法调用。后一个函数使我们能够将对象作为带有一些参数(在模板第一行中声明的参数)的函数来调用。

这个对象也依赖于像BaseScalaTemplate这样的结构。它是用输出格式化程序(Html)构建的。该格式化程序将能够接受一些内容(例如 StringUnitSeq[Int]Map[A,B] , ...) 并将其渲染为 HTML 代码。

格式化将在使用BaseScalaTemplate_display_方法时进行,该方法返回格式化输出的实例。此显示方法将在对象的 apply 方法主体中的 .scala.html 文件的编译代码中调用。

所以正文可以这样结束:

def apply/*1.2*/(testMap:scala.collection.immutable.Map[String, Int]):play.api.templates.Html = 
  _display_ {
    Seq[Any](
      _display_(
        Seq[Any](
          /*3.2*/testMap/*3.9*/.map/*3.13*/ { e =>
            _display_(Seq[Any](_display_(Seq[Any](/*5.3*/e))))
          }
        )
      )
    )
  }

看到了吗? _display_ 调用不会改变任何内容,但它们的组合方式使得 apply 本身将返回格式化代码 (Html) 的实例!

这给了我们线索......

是啊等等……现在为什么?

在给出了有关 Play 内部结构的闪电之后,我们现在可以解决真正的问题:为什么问题帖子中提供的意识形态 Scala 代码不起作用......阅读,根本不输出任何内容。

这非常简单,当在 Map 上使用 foreach 时,您确实循环项目并适应 将它们转换为 Html。但模板系统无法使用这些计算,因为它们包含在 foreach 循环中。也就是说,当序列中的每个项目都需要副作用时,必须使用 foreach...并在完成后返回 Unit

因为,模板系统将尝试_display_在给定的Mapforeach的结果,它只会渲染/格式化 Unit,因此是一个空的String!

总而言之,只需使用 map 即可返回一个新序列,其中包含适应项目,即 Html 实例。

嗯,那么 for 呢?

是的,你是对的...根据所说的,为什么建议使用 for 循环的答案有效,因为在不产生值的情况下,一个 for 相当于 foreach!? (引入 yield 将以类似于 map 的行为结束)

答案就在代码中...模板编译器会将 yield 关键字添加到 for 的主体中 - 请查看 here 。 :-D

,它也有效,因为 for 主体中生成的内容将在完成后附加到返回的序列中。

关于templates - 玩! Framework 2.0 - 循环遍历 scala 模板中的 map ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9946552/

相关文章:

mysql - Play +光滑 : How to do partial model updates?

playframework - 如何配置 Play Framework 以将我的 Artifactory 存储库用于所有依赖项?

c++ - 类的部分模板特化

c++ - 如何在.cpp中实现属于非模板类的模板函数

scala - akka 中的 -Dconfig.resource 和 -Dconfig.file 有什么区别?

scala - 在 Scala 中重新创建 Haskell 的 `replicateM` 的行为

arrays - Scala 将 IndexedSeq[AnyVal] 转换为 Array[Int]

java - 空响应,当我应该获取 xml 时

c++ - 模板和派生类定义 : error: 'myClass' is not a class, 命名空间,或枚举

c++ - 模板函数特化说明