为简单起见,假设我有一个列表列表。我想显示一个html表,其中顶级列表的每个元素都有一行,并且该行中的每一列都是子列表的元素。
所以
List(List(1,2,3), List(4,5,6), List(7,8,9))
会导致html表格显示如下:
1 2 3
4 5 6
7 8 9
10 11 12
这是我的尝试(模板)
<table>
<lift:viewQuery.res2>
<tr>
<a:row>
<td><a:num/></td>
</a:row>
</tr>
</lift:viewQuery.res2>
</table>
以及代码段中的相关方法:
def res2(in :NodeSeq) : NodeSeq = {
val data = List(List(1,2,3), List(4,5,6), List(7,8,9), List(10,11,12))
def bindChild(child : List[Int],in :NodeSeq) = {
child.flatMap(c => Helpers.bind("a", in,
"num" -> c.toString))
}
data.flatMap(childList => Helpers.bind("a", in,
"row" -> bindChild(childList, in)))
}
当我转到页面时,它会给我以下错误:
error on line 28 at column 23: Namespace prefix a on row is not defined
error on line 29 at column 31: Namespace prefix a on num is not defined
error on line 34 at column 23: Namespace prefix a on row is not defined
error on line 35 at column 31: Namespace prefix a on num is not defined
...
有关处理此问题的最佳方法的任何想法吗?
答案 0 :(得分:2)
如果您不需要特定于电梯的答案,那么这样的事情可以起作用
val data = List(List(1,2,3), List(4,5,6), List(7,8,9))
<table>{data.map(row => <tr>{row.map(col => <td>{col}</td>)}</tr>)}</table>
您的实际用例可能有点复杂,因此可能不适用。
答案 1 :(得分:2)
你很亲密。试试这个:
<table>
<lift:viewQuery.res2>
<a:row>
<tr>
<b:cell><td><cell:num/></td></b:cell>
</tr>
</a:row>
</lift:viewQuery.res2>
</table>
对于你的片段:
def res2(in :NodeSeq) : NodeSeq = {
import Helpers._
val data = List(List(1,2,3), List(4,5,6), List(7,8,9), List(10,11,12))
def cell(x: List[Int])(template: NodeSeq) =
x.flatMap{y: Int => bind("cell", template, "num" -> y) }
def row(x: List[List[Int]])(template: NodeSeq) =
x.flatMap {y => bind("b", template, "cell" -> { x: NodeSeq => cell(y)(x)} ) }
bind("a", in, "row" -> { x: NodeSeq => row(data)(x) })
}
我已经离开某些类型并且更加明确,所以你可以看到究竟发生了什么。您的问题是您在每个级别使用相同的模板in
,而您想要做的是逐渐缩小模板范围。因此,在上面的模板中,我们希望<a:row>
标记内的所有内容都针对列表中的每个顶级项重复,然后<b:cell>
内的所有内容重复每个Int
。这样做的方法是创建一个FuncBindParam
,这是我们正在使用以下行:
"row" -> { x: NodeSeq => row(data)(x) }
然后,Lift将传递包含在<a:row>
标记内的xhtml作为curried函数的参数。并且在curried函数内部的flatMap调用会根据需要多次重复模板。