Snap:带有heist的内/外循环

时间:2012-12-06 11:49:17

标签: haskell haskell-snap-framework

我不确定我是否正确地在标题中表达了这个问题,但这是情况...... 当表字段(模式)仅在运行时可用时,我需要使用heist创建一个动态表。 通常,当在编译时已知模式时,我会这样做:

<table>
  <row-splice>
    <tr>
      <td> <field1/> </td>
      <td> <field2/> </td>
      <td> <field3/> </td>
    </tr>
  </row-splice>
</table>

那时我在编译时知道字段数及其名称。 我理解如何使用'runChildrenWith','mapSplices'等处理处理程序中的所有内容......

现在我遇到的情况是字段和架构的数量仅在运行时可用。 因此,根据我的理解,抢劫模板看起来像这样:

<table>
  <row-splice>
    <tr>
      <field-splice>
      <td> <field/> </td>
      </field-splice>
    </tr>
  </row-splice>
</table>

我真的很困惑如何在处理程序中实现它。我想我需要做两次'mapSplices' - 一个在另一个里面,对吗?所以,从经验上来说,这将是一个内外循环/地图,对吧?

我如何在处理程序中执行此操作?

感谢。

更新

忘记提及可以在运行时从数据库中检索模式,并将其作为:

Table { tableName   :: Text
      , tableFields :: [Text]
      }

但实际上并不需要它,因为数据来自无模式的mongodb并转换为Map:

fromList [("FieldName1","Value1"),("FieldName2","Value2"),("FieldName3","Value3")]

UPDATE2:

我尝试过没有运气的建议示例我只是将所有数据都放在一个列中。 我只需要一个简单的内部和外部循环来动态生成字段和行。 这不可能更简单:

<% @rows.each do |row| %>
  <tr>
  <% row.each do |field| %>
    <td> <%= field %> </td> 
  <% end %>
  </tr>
<% end %>

UPDATE3:

经过漫长的周末休息后,我终于破解了它...... 这是一个例子。这是mongodb特定的,我只是复制和粘贴它。 但是,如果有人卡住内/外循环,我认为这会有所帮助。

showTableH :: AppHandler ()
showTableH = do
  table <- liftIO $ fetchTable tname
  docs <- liftIO $ getColList tname
  let rowSplice doc = mapSplices (\f -> fieldSplice $ T.pack $ at f doc) (tableFields table)
    where fieldSplice field = runChildrenWithText [("field", field)]
  let listRowsSplice = mapSplices (\d -> runChildrenWith [("fields", rowSplice d)]) docs
  heistLocal (bindSplices [("rows", listRowsSplice)]) $ render "show-table"

1 个答案:

答案 0 :(得分:2)

我认为这里的关键是使用mapSplices和runChildrenWith。我认为它看起来像这样:

rowSplice = do
    rows <- lift getRowsFromDB
    mapSplices (\row -> runChildrenWith [("field-splice", fieldSplice row)]) rows
fieldSplice rowId = do
    fields <- lift $ getFieldsFromDB rowId
    mapSplices (\f -> runChildrenWith [("field", fieldToText f)]) fields