如何在 IHP 表单中传递列表参数?
How can I pass List params in IHP forms?
我正在尝试在 IHP 的表单中进行多项选择。目前正在尝试通过视图中的多个复选框解决此问题。
renderIngredientSelection :: Ingredient -> Html
renderIngredientSelection ingredient = [hsx|
<li>
<input name="ingredients" type="checkbox" value={(get #name ingredient)} />{get #name ingredient}
</li>
|]
所以网络日志的浏览器工具说它正在正确发送这样的请求。
barcode=5555555555555&name=Pancake&ingredients=milk&ingredients=egg
但是在控制器中,param
函数只会捕获第一个ingredients
参数。
有没有办法在控制器中捕获所有这些参数?我在网络日志中看到,创建了一个包含所有参数的元组列表,包括 ingredients
参数。我如何访问它并将其映射到像 ["milk", "egg"]
?
这样的列表中
您可以使用 allParams
访问您在日志中看到的完整请求参数。
对于这样的请求:
barcode=5555555555555&name=Pancake&ingredients=milk&ingredients=egg
我们可以这样使用allParams
:
action MyAction = do
let ingredients = allParams
-- ingredients = [("barcode",Just "5555555555555"),("name",Just "Pancake"),("ingredients",Just "milk"),("ingredients",Just "egg")]
我们仍然需要过滤此列表以仅 return 成分值:
action MyAction = do
let ingredients = allParams
|> filter (\(paramName, paramValue) -> paramName == "ingredients")
-- ingredients = [("ingredients",Just "milk"),("ingredients",Just "egg")]
现在我们需要将此 key-value-map 映射到值。因为该值是一个可能(如 Just "milk"
),我们将使用 mapMaybe
而不是 map
。 mapMaybe
丢弃所有 Nothing
值并解压 Just
:
action MyAction = do
let ingredients = allParams
|> filter (\(paramName, paramValue) -> paramName == "ingredients")
|> mapMaybe (\(paramName, paramValue) -> paramValue)
-- ingredients = ["milk", "ingredients"]
我们现在有一个 [ByteString]
。我们正在处理的大多数函数都期望 Text
而不是 ByteString
,因此让我们使用 cs
(cs 是转换字符串的缩写)[=54 进行转换=]:
action MyAction = do
let ingredients :: [Text] = allParams
|> filter (\(paramName, paramValue) -> paramName == "ingredients")
|> mapMaybe (\(paramName, paramValue) -> paramValue)
|> map cs
-- ingredients = ["milk", "ingredients"]
将其移动到 Application/Controller/Helper.hs
为了更好的代码结构,我将此函数移出到 Application/Controller/Helper.hs
,如下所示:
module Application.Helper.Controller
( ...
, paramList -- Don't forget the export :)
)
paramList name = allParams
|> filter (\(paramName, paramValue) -> paramName == name)
|> mapMaybe (\(paramName, paramValue) -> paramValue)
|> map cs
然后像这样在控制器中使用它:
action MyAction = do
let ingredients = paramList "ingredients"
Application.Helper.Controller
中的所有功能在我们的控制器中自动可用。
我正在尝试在 IHP 的表单中进行多项选择。目前正在尝试通过视图中的多个复选框解决此问题。
renderIngredientSelection :: Ingredient -> Html
renderIngredientSelection ingredient = [hsx|
<li>
<input name="ingredients" type="checkbox" value={(get #name ingredient)} />{get #name ingredient}
</li>
|]
所以网络日志的浏览器工具说它正在正确发送这样的请求。
barcode=5555555555555&name=Pancake&ingredients=milk&ingredients=egg
但是在控制器中,param
函数只会捕获第一个ingredients
参数。
有没有办法在控制器中捕获所有这些参数?我在网络日志中看到,创建了一个包含所有参数的元组列表,包括 ingredients
参数。我如何访问它并将其映射到像 ["milk", "egg"]
?
您可以使用 allParams
访问您在日志中看到的完整请求参数。
对于这样的请求:
barcode=5555555555555&name=Pancake&ingredients=milk&ingredients=egg
我们可以这样使用allParams
:
action MyAction = do
let ingredients = allParams
-- ingredients = [("barcode",Just "5555555555555"),("name",Just "Pancake"),("ingredients",Just "milk"),("ingredients",Just "egg")]
我们仍然需要过滤此列表以仅 return 成分值:
action MyAction = do
let ingredients = allParams
|> filter (\(paramName, paramValue) -> paramName == "ingredients")
-- ingredients = [("ingredients",Just "milk"),("ingredients",Just "egg")]
现在我们需要将此 key-value-map 映射到值。因为该值是一个可能(如 Just "milk"
),我们将使用 mapMaybe
而不是 map
。 mapMaybe
丢弃所有 Nothing
值并解压 Just
:
action MyAction = do
let ingredients = allParams
|> filter (\(paramName, paramValue) -> paramName == "ingredients")
|> mapMaybe (\(paramName, paramValue) -> paramValue)
-- ingredients = ["milk", "ingredients"]
我们现在有一个 [ByteString]
。我们正在处理的大多数函数都期望 Text
而不是 ByteString
,因此让我们使用 cs
(cs 是转换字符串的缩写)[=54 进行转换=]:
action MyAction = do
let ingredients :: [Text] = allParams
|> filter (\(paramName, paramValue) -> paramName == "ingredients")
|> mapMaybe (\(paramName, paramValue) -> paramValue)
|> map cs
-- ingredients = ["milk", "ingredients"]
将其移动到 Application/Controller/Helper.hs
为了更好的代码结构,我将此函数移出到 Application/Controller/Helper.hs
,如下所示:
module Application.Helper.Controller
( ...
, paramList -- Don't forget the export :)
)
paramList name = allParams
|> filter (\(paramName, paramValue) -> paramName == name)
|> mapMaybe (\(paramName, paramValue) -> paramValue)
|> map cs
然后像这样在控制器中使用它:
action MyAction = do
let ingredients = paramList "ingredients"
Application.Helper.Controller
中的所有功能在我们的控制器中自动可用。