代码之家  ›  专栏  ›  技术社区  ›  danbroooks

处理Yesod表单中的数据集合

  •  2
  • danbroooks  · 技术社区  · 6 年前

    有可能吗 Yesod 处理包含数据集合的窗体?

    我有一个表单,用户可以向其中添加多个人,在前端,它当前的外观如下:

    { people.map((person, key) => (
      <td>
        <input type="hidden" name={ `person[${key}][firstName]` } value={person.firstName} />
        <input type="hidden" name={ `person[${key}][lastName]` } value={person.lastName} />
        { person.firstName } { person.lastName }
      </td>
    )) }
    

    然后我希望能够将其转换到后端,如下所示:

    [Person "Michael" "Snoyman", Person "Ed" "Kmett"]
    

    这个列表的长度是可变的,所以它可以有尽可能多的人 people 用户喜欢的价值。到目前为止,我还无法用计算机来复制这种东西 FormInput 是的。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Isaac van Bakel    6 年前

    你可以自己创造 FormInput 通过定义 unFormInput 功能。这个函数可以从表单中提取字段名,提取键,然后使用 ireq 推广相关领域。

    这看起来像

    getPeople :: FormInput (your handler type) [People]
    getPeople = FormInput $ \m l env fenv ->
        (unFormInput (peopleField peopleKeys)) m l env fenv
            where
                peopleKeys = getPeopleKeys env
    

    这个helper函数将为表单中的人员生成所有键值。它们还不需要是有效的,因为字段解析稍后会处理这个问题。

    getPeopleKeys :: Env -> [Text]
    getPeopleKeys env = mapMaybe extractKey (keys env)
        where
            extractKey :: Text -> Maybe Text
            extractKey key = ... -- you could use e.g. regex here
                                 -- to pull the keys out of the field names
                                 -- and return Nothing otherwise
    

    peopleField公司

    此助手生成 . 它

    1. 拿了一张钥匙清单,
    2. 生成 从每一个
      1. 为名字和姓氏生成一个字段
      2. 把这些领域变成 表格输入
      3. 表格输入 把它们组合成一个 Person
    3. 连接 表格输入 FormInput ... [Person]

    peopleField :: Monad m => RenderMessage (HandlerSite m) FormMessage => [Text] -> FormInput m [Person]
    peopleField = mapM personField
        where
            personField :: Text -> Field ... Person
            personField key = (liftA2 (Person)) (personFNameField) (personLNameField)
                where
                    personFNameField = (ireq hiddenField) . fNameField key
                    personLNameField = (ireq hiddenField) . lNameField key
    
    fNameField key = ... -- this outputs "person[${key}][firstName]"
    lNameField key = ... -- etc.