【问题标题】:Handling a collection of data in a Yesod Form处理 Yesod 表单中的数据集合
【发布时间】:2018-09-10 00:35:19
【问题描述】:

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 值中包含用户喜欢的尽可能多的人。到目前为止,我一直无法弄清楚如何在 Yesod 中使用 FormInput 来复制这种东西。

【问题讨论】:

    标签: forms haskell yesod


    【解决方案1】:

    您可以通过定义unFormInput 函数来创建自己的FormInput。该功能可以从表单中提取字段名称,提取键,然后您可以使用ireq 来提升相关字段。

    这可能看起来像

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

    getPeopleKeys

    此辅助函数将为表单中的人员生成所有键值。它们还不需要有效,因为字段解析将在稍后处理。

    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

    这个助手产生FormInput。它

    1. 获取键列表,
    2. 从每个生成一个FormInput
      1. 为名字和姓氏生成一个字段
      2. 将这些字段转换为FormInputs
      3. 产生一个FormInput,它将它们组合成一个Person
    3. FormInputs 的结果连接成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.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多