如何创建具有未知(在构建时)列数的表

发布于 2024-09-26 05:48:39 字数 1393 浏览 4 评论 0原文

为简单起见,假设我有一个列表列表。我想显示一个 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
...

关于处理此问题的最佳方法的任何想法?

For simplicity, imagine that I have a list of lists. I want to display a html table where there is a row for each element of the top-level list and each column in the row is an element of the child list.

So

List(List(1,2,3), List(4,5,6), List(7,8,9))

would result in an html table that is displayed like this:

1     2     3
4     5     6
7     8     9
10    11    12

Here's my attempt (the template)

    <table>
        <lift:viewQuery.res2>
            <tr>
            <a:row>
                <td><a:num/></td>
            </a:row>
            </tr>
        </lift:viewQuery.res2>
    </table>

And the relevant method in the snippet:

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)))
}

When i go to the page it gives me the following errors:

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
...

Any ideas on the best way to handle this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

单调的奢华 2024-10-03 05:48:39

你很接近。试试这个:

<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) })
}

我留下了一些类型并且更加明确,这样你就可以看到到底发生了什么。您的问题是,您在每个级别都使用相同的模板,而您想要做的是逐步缩小模板范围。因此,在上面的模板中,我们希望对列表的每个顶级项目重复 标记内的所有内容,然后对 内的所有内容重复。 对每个 Int 重复。实现此目的的方法是创建一个 FuncBindParam,这就是我们对以下行所做的事情:

 "row" -> { x: NodeSeq => row(data)(x) }

Lift 将传入 中包含的 xhtml ; 标记作为柯里化函数的参数。柯里化函数内部的 flatMap 调用负责根据需要多次重复模板。

You are close. Try this:

<table>
    <lift:viewQuery.res2>
        <a:row>
        <tr>
            <b:cell><td><cell:num/></td></b:cell>
        </tr>
        </a:row>
    </lift:viewQuery.res2>
</table>

And for your snippet:

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) })
}

I've left in some types and been a bit more explicit so you can see what exactly is going on. Your problem was that you were using the same template in for every level, when what you wanted to do was progressively narrow down the template. So in the above template, we want everything inside of the <a:row> tags to repeat for each top level item of the list and then everything inside of <b:cell> to repeat for each Int. The way to do that is by creating a FuncBindParam which is what we're doing with the following line:

 "row" -> { x: NodeSeq => row(data)(x) }

Lift will then pass in the xhtml that was contained inside of the <a:row> tag as an argument to the curried function. And the flatMap calls inside of the curried functions take care of repeating the template as many times as are needed.

栩栩如生 2024-10-03 05:48:39

如果您不需要特定于 Lift 的答案,类似的方法可能会起作用,

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>

但您的实际用例可能会更复杂一些,因此这可能不适用。

If you don't need a Lift-specific answer, something like this could work

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>

Your actual use case might be a bit more complex though, so this might not be applicable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文