嗯,这是我努力克服的编译拼接的另一个障碍。 当我第一次使用原始解释的拼接时,我遇到了一些麻烦,现在我无法将其翻译成已编译的变体。
此处描述了原始问题: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
我可以使用解释的varian执行此操作而不会出现问题。 tableRawS的解释示例由ducument参数化,但映射在[labels]上。我无法在编译变体中实现这一点。我需要tableRaw函数中的文档和标签列表,因此我可以将不同的单元拼接绑定到文档之外。这真的很痛苦。我不知道怎么做。无论我做什么,我最终都会使用tableRaw映射文档而不是映射标签列表。
基本上。我使用上面提到的文档结构从数据库中获取[文档],并从数据库中获取标签,其中
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>
答案 0 :(得分:3)
假设这是我们想要呈现为表格的结构:
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>
mytable
,mycaptiontext
,myrow
,mydata
和mydatavalue
是绑定到拼接的标记。特别是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
机器。)
我们可以将tableSplice
与runtime
结合使用,并将结果注册为Heist配置中的顶级拼接,绑定到mytable
标记。像这样:
let heistConfig = mempty {
hcCompiledSplices = do
"mytable" ## (tableSplice runtime)
.... other top-level splices here ...
}
这应该有用。
可以在this tutorial中找到更多使用编译的Heist渲染嵌套结构的示例。