【问题标题】:Snap: rendering table with compiled splicesSnap:带有编译拼接的渲染表
【发布时间】:2013-11-03 20:57:48
【问题描述】:

嗯,这是我难以克服的编译拼接的另一个障碍。 当我第一次使用原始的解释拼接时遇到了一些麻烦,现在我被困在将其翻译为编译的变体。

这里描述了原始问题:rendering a table

所以我需要构建这样的结构:

map (\doc -> fmap (\f -> splice $ f at doc) fields ) documents

这只是外部和内部循环,外部渲染原始数据和内部渲染单元格。这一切都在原始链接中进行了描述。

它目前以这样的解释模式实现:

tableRawS raw = mapSplices (\f -> tableCellS $ T.pack $ at f raw) (tableFields table)
  where tableCellS cell = runChildrenWithText $ "table-cell" ## cell

tableBodyS = mapSplices (\d -> runChildrenWith $ raws d) documents
  where docID d = T.pack $ show $ valueAt "_id" d
        raws d = do "table-raw" ## tableRawS d
                    "raw-id" ## textSplice $ docID d

我已经苦苦挣扎了几天,没有任何结果。这可能是由于缺乏对编译拼接 API 的理解。请帮忙!

编辑

我没有为我的问题提供足够的详细信息。我设法得到的上述解释变体的最佳近似值是:

tableBody = manyWithSplices runChildren tableRaw $ lift documents
tableRaw doc = do "table-raw" ## manyWithSplices runChildren rawCell $ lift labels
                    where rawCell label = "table-cell" ## pureSplice . textSplice $ at label doc 
                  "table-rawid" ## pureSplice . textSplice $ at "_id" doc
                    where oid = T.pack . show. valueAt "_id"

它不起作用!问题是翻译原始渲染函数,即 tableRaw。所以我会提供更多细节。 我输入 tableBody 的数据是一个类似 Map 的结构列表:

document = ["_id" =: 12345, "name" =: "pretty", "model" =: "cool", "size" =: "big"]

所以要以原始形式提取数据,我需要映射标签列表

map (\l -> at l document) labels

我可以毫无问题地使用解释的变量来做到这一点。 tableRawS 的解释示例由文档参数化,但映射到 [labels]。我无法在编译的变体中实现这一点。我需要 tableRaw 函数中存在的文档和标签列表,以便我可以将不同的单元格拼接从文档中绑定出来。这是真正的痛苦。我不知道该怎么做。无论我做什么,我最终都会使用 tableRaw 映射到文档而不是映射到标签列表。

基本上。我从具有上述文档结构的数据库中获取 [document],并从数据库中获取标签,其中

 labels = ["name", "model", "size"] -- table fields

我使用“at :: Label -> Value”从文档中获取数据 有了这些,我该如何渲染这个模板:

<table class="table" data-title=${table-name}>
<thead>
  <tr>
    <th>#</th>
    <table-head>
      <th> <table-hcell/> </th>
    </table-head>
  </tr>
</thead>
<tbody>
  <table-body>
    <tr data-oid=${table-rowid}>
      <td> <input type="checkbox"/> </td>
      <table-raw>
        <td> <table-rcell/> </td>
      </table-raw>
    </tr>
  </table-body>
</tbody>

【问题讨论】:

    标签: haskell haskell-snap-framework heist


    【解决方案1】:

    假设这是我们想要呈现为表格的结构:

    data Table = Table 
        {
          caption :: T.Text
        , rows :: [[Int]]
        }
    

    一个简单的模板可能是这样的

    <body>
        <mytable>
        <table>
            <caption><mycaptiontext/></caption>
            <myrow>
            <tr>
                <mydata>
                <td><mydatavalue/></td>
                </mydata>
            </tr>
            </myrow>
        </table>
        </mytable>
    </body>  
    

    其中mytablemycaptiontextmyrowmydatamydatavalue 是将绑定到拼接的标签。 mytable 尤其会绑定到顶级拼接。

    需要考虑三个级别:整个表、行和行内的数据。对于每个级别,我们将定义一个函数,该函数接受运行时操作并返回编译后的拼接。

    对于“行数据”级别,运行时操作携带一行中的值列表:

    dataSplice :: Monad m => RuntimeSplice m [Int] -> C.Splice m
    dataSplice = C.manyWithSplices C.runChildren splicefuncs 
        where
        splicefuncs = do
            "mydatavalue"  ## (C.pureSplice . C.textSplice $ T.pack . show)
    

    对于“行”级别,运行时操作携带完整的行列表:

    rowSplice :: Monad m => RuntimeSplice m [[Int]] -> C.Splice m
    rowSplice = C.manyWithSplices C.runChildren splicefuncs 
        where
        splicefuncs = do
            "mydata"  ## dataSplice
    

    注意我们如何在定义中使用dataSplice

    对于“整表”级别,运行时操作携带Table

    tableSplice :: Monad m => RuntimeSplice m Table -> Splice m
    tableSplice = C.withSplices C.runChildren splicefuncs 
        where              
        splicefuncs = do  
            "mycaptiontext" ## (C.pureSplice . C.textSplice $ caption)
            "myrow"   ## (rowSplice .  liftM rows)    
    

    注意我们在这里如何使用liftM,将RuntimeSplice m Table 转换为RuntimeSplice m [[Int]],以便该类型符合rowSplice 的预期。

    现在假设我们有一个生成表数据的运行时操作:

    runtime :: Monad m => RuntimeSplice m Table
    runtime = return $ Table "This is the caption" $
                [ [3, 5, 6], [8, 3, 7 ] ]  
    

    (这个很简单。例如,更复杂的操作可以从数据库中获取数据。请记住,在 Snap 中,RuntimeSplices 可以访问所有 Snaplet 机器。)

    我们可以将tableSpliceruntime 结合起来,并将结果注册为Heist 配置中的顶级拼接,绑定到mytable 标签。像这样:

    let heistConfig = mempty { 
                         hcCompiledSplices = do
                               "mytable" ## (tableSplice runtime)
                               .... other top-level splices here ...
                        }
    

    这应该可行。

    更多使用编译的 Heist 渲染嵌套结构的示例可以在 this tutorial 中找到。

    【讨论】:

    • 谢谢,丹尼尔。很棒的教程。我需要这样的东西。很多例子可以借鉴。至于我的问题,我想我有点设法弄清楚如何渲染一张桌子。它只是不适用于我的具体示例。我用一些细节更新了我的问题,但我不确定我是否正确解释了自己......请查看解释的变体以了解这个想法。
    • 不幸的是,这个例子对我不起作用。要么我做错了什么,但就像没有为我解释接头一样。在 Snap 中,我注册顶级拼接如下:addConfig h $ mempty { hcCompiledSplices = do "mytable" ## (tableSplice runtime) }
    猜你喜欢
    • 2013-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-21
    • 1970-01-01
    • 2019-09-26
    • 1970-01-01
    • 2019-01-29
    相关资源
    最近更新 更多