Happstack handling



我正在解析happstack中的表单,但我不知道有什么更简洁的方法可以在服务器上收集表单变量。有人知道这里是否有减少所需代码量的技巧吗?

 formHandler = do
    method POST
    delA1       <- look "address-01-delivery"
    delA2       <- look "address-02-delivery"
    delSuburb   <- look "suburb-delivery"
    delPostcode <- look "postcode-delivery"
    delState    <- look "state-delivery"
    delCountry  <- look "country-delivery"
    bilA1       <- look "address-01-billing"
    bilA2       <- look "address-02-billing"
    bilSuburb   <- look "suburb-billing"
    bilPostcode <- look "postcode-billing"
    bilState    <- look "state-billing"
    bilCountry  <- look "country-billing"

前言:这显然不会减少您在上面发布的代码量,但从长远来看,它可能会使事情更易于维护,因为它提供了一种一致的验证方法,并允许您处理强类型对象,而不是大量的文本值

如果您要进行任何数量的表单处理,我建议您使用表单库。我个人使用过消化函数,并发现使用它很愉快。此外,它还附带了一个Hapstack后端,这使得Hapstack集成非常直接。

这可能比你想投资的更多,但这里有一个使用消化函数的表单代码的示例。我没有尝试编译这些内容,所以它可能起作用,也可能不起作用,但希望它能提供大致的想法。

{-# LANGUAGE OverloadedStrings #-}
module Forms where
import Control.Applicative ((<$>), (<*>))
import Data.Text (Text)
import qualified Data.Text as T
import Happstack.Server
import Text.Digestive

data AddressState 
  = Alabama
  | Alaska
  | Arkansas
  -- ...
  deriving (Enum, Eq, Read)
data Country
  = Canada
  | Mexico
  | UnitedStates
  -- ...
  deriving (Enum, Eq, Read)
data Address = Address
  { street1  :: Text
  , street2  :: Maybe Text
  , suburb   :: Maybe Text
  , postcode :: Int
  , state    :: AddressState
  , country  :: Country
  }
data ShippingForm = ShippingForm
  { deliveryAddress :: Address
  , billingAddress  :: Address
  }
addressForm :: (Monad m) => Form Text m Address
addressForm = Address
  <$> "street1"  .: nonEmptyText (text Nothing)
  <*> "street2"  .: optionalText Nothing
  <*> "suburb"   .: optionalText Nothing
  <*> "postcode" .: stringRead "Please enter a valid postcode" Nothing
  <*> "state"    .: choice mkChoices Nothing
  <*> "country"  .: choice mkChoices Nothing
  where
    nonEmptyText = check "Cannot be empty" (not . T.null)
    mkChoices = [(x, T.pack (show x)) | x <- [minBound .. maxBound]]
shippingForm :: (Monad m) => Form Text m ShippingForm
shippingForm = ShippingForm
  <$> "delivery" .: addressForm
  <*> "billing"  .: addressForm
formHandler :: ServerPart Response
formHandler = do
  method POST
  decodeBody $ defaultBodyPolicy "/tmp" 4096 4096 4096
  res <- runForm "shipping" shippingForm
  case res of
    (view, Nothing) -> do
      -- setup your view
      ok $ toResponse () -- <-- replace this with your view code
    (_, Just formData) -> do
      -- here, formData is a fully valid `ShippingForm`
      let delStreet1 = (street1 . deliveryAddress) formData
      -- do whatever you need to with this data (ie: persist it to a database, etc)
      ok $ toResponse ()

想要了解一些关于消化功能因子的好文章,你可以查看以下链接:

消化功能教程

ocharles的博客文章

相关内容

  • 没有找到相关文章

最新更新