wfb*_*ale 14 templates scala playframework playframework-2.0
我有一个表示目录的地图,它包含Chapter键和List[Section]值.现在我试图在我的模板中循环这样:
<dl>
@table_of_contents.foreach((e) => {
<dt>
@e._1.title
</dt>
for(section <- e._2){
<dd>
@section.title
</dd>
}
})
</dl>
Run Code Online (Sandbox Code Playgroud)
我目前没有输出<dl>.
我println(table_of_contents)在模板的顶部添加了一个语句,以确保映射确实具有数据并打印出来:
{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>
}
}
Run Code Online (Sandbox Code Playgroud)
and*_*lla 18
TL;博士
到目前为止给出的答案(@wbarksdale,@ PlexQ和@Daniel C. Sobral在评论中)足以解决这里描述的问题.
但他们错过了关于为什么初始代码使用foreach不起作用的真实解释.
因为foreach退货而无法运作Unit.
玩概念
让我快速回顾一下模板的工作原理.
Play框架2中默认提供的Scala模板系统确实是基于FP概念构建的,因此它使用了大量不可变结构等等.
此外,这样的Scala模板(比如说myTemplate.scala.html)将被编译成一个常规的Scala object,它有一个apply名为的方法.后一个函数使我们能够将对象作为一个函数调用一些参数(在模板的第一行中声明的参数).
这object也依赖于BaseScalaTemplate使用输出格式化程序(Html)构建的构造.这种格式将能够利用的东西(如String,Unit,Seq[Int],Map[A,B],...),并呈现到HTML代码.
使用_display_方法时将进行格式化,该方法BaseScalaTemplate返回格式化输出的实例.这个显示方法将在对象方法体中文件的编译代码中调用..scala.htmlapply
所以身体可能会这样结束:
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))))
}
)
)
)
}
Run Code Online (Sandbox Code Playgroud)
看到?该_display_调用不变异什么,但它们在适用本身将返回格式化代码的实例,这样组成的(Html)!
这给了我们线索......
是啊等等......现在为什么?
在给出关于Play内部的闪电之后,我们现在可以解决真正的问题:为什么地狱是问题帖子中提供的意识形态Scala代码不起作用...读取,根本不输出任何内容.
这很简单,当你foreach在a上使用时Map,你确实在循环这些项目并使它们适应 Html.但是模板系统无法使用这些计算,因为它们被包含在foreach循环中.即foreach具有在需要的序列中的每一项副作用使用......并返回Unit时,它的完成.
因为,模板系统将尝试在给定_display_的结果foreach上Map它将简单地渲染/格式Unit,因此是空的String!
总而言之,只需使用map它将返回一个包含适应项目的新序列,即Html实例.
嗯,怎么样for?
是的,你是对的...根据已经说过的,为什么建议使用for循环工作的答案,因为没有产生一个值,a for相当于foreach!?(介绍yield将以类似map行为结束)
答案在代码中......模板编译器会将yield关键字添加到for主体 - 请在此处查看.:-D
Etvoilà,它也有效,因为生成的东西for会在完成之后附加到返回的序列中.
wfb*_*ale 17
我提出的解决方案看起来像这样.基本上它只是避免使用我目前正常使用的函数式编程,但我仍然希望看到一个使用scala函数式的工作解决方案.
<dl>
@for((key, value) <- table_of_contents) {
<dt>
@key.getTitle
</dt>
@displaySections(value)
}
</dl>
@displaySections(sections: List[Section]) = {
@for(a_section <- sections) {
<dd>@a_section.getTitle</li>
}
}
Run Code Online (Sandbox Code Playgroud)
Scala中的游戏非常好地使用了Scala的功能特性.将其更改为返回元素的地图,它应该可以工作.
<dl>
@table_of_contents.map( case(k,v) => {
<dt>
@k.title
</dt>
@v.map { section =>
<dd>
@section.title
</dd>
}
})
</dl>
Run Code Online (Sandbox Code Playgroud)
根据上面的建议,在这种情况下,它将它变成一个部分功能,可以很好地完成我们想要的功能!
| 归档时间: |
|
| 查看次数: |
17890 次 |
| 最近记录: |