我正在尝试在 IHP 中制作表单的多项选择部分。目前正在尝试在视图中使用多个类似这样的复选框来解决它。
renderIngredientSelection :: Ingredient -> Html
renderIngredientSelection ingredient = [hsx|
<li>
<input name="ingredients" type="checkbox" value={(get #name ingredient)} />{get #name ingredient}
</li>
|]
Run Code Online (Sandbox Code Playgroud)
所以网络日志的浏览器工具说它正在正确发送这样的请求。
barcode=5555555555555&name=Pancake&ingredients=milk&ingredients=egg
Run Code Online (Sandbox Code Playgroud)
但是在控制器中,该param函数只会捕获第一个ingredients参数。
有没有办法在控制器中捕获所有这些参数?我在网络日志中看到,创建了一个包含所有参数的元组列表,包括两个ingredients参数。我如何访问它并将其映射到一个列表中["milk", "egg"]?
小智 6
您可以使用allParams访问您在日志中看到的完整请求参数。
对于像这样的请求:
barcode=5555555555555&name=Pancake&ingredients=milk&ingredients=egg
Run Code Online (Sandbox Code Playgroud)
我们可以这样使用allParams:
barcode=5555555555555&name=Pancake&ingredients=milk&ingredients=egg
Run Code Online (Sandbox Code Playgroud)
我们仍然需要过滤这个列表以只返回成分值:
action MyAction = do
let ingredients = allParams
-- ingredients = [("barcode",Just "5555555555555"),("name",Just "Pancake"),("ingredients",Just "milk"),("ingredients",Just "egg")]
Run Code Online (Sandbox Code Playgroud)
现在我们需要将此键值映射仅映射到值。因为该值是一个可能(例如Just "milk"),所以我们将使用mapMaybe代替map。mapMaybe丢弃所有Nothing值并解压Just:
action MyAction = do
let ingredients = allParams
|> filter (\(paramName, paramValue) -> paramName == "ingredients")
-- ingredients = [("ingredients",Just "milk"),("ingredients",Just "egg")]
Run Code Online (Sandbox Code Playgroud)
我们有一个[ByteString]现在。我们处理的大多数函数都期望 aText而不是 a ByteString,因此让我们使用cs (cs 是 convert string 的缩写) 进行转换:
action MyAction = do
let ingredients = allParams
|> filter (\(paramName, paramValue) -> paramName == "ingredients")
|> mapMaybe (\(paramName, paramValue) -> paramValue)
-- ingredients = ["milk", "ingredients"]
Run Code Online (Sandbox Code Playgroud)
Application/Controller/Helper.hs对于一个不错的代码结构,我会将这个函数移出Application/Controller/Helper.hs如下:
action MyAction = do
let ingredients :: [Text] = allParams
|> filter (\(paramName, paramValue) -> paramName == "ingredients")
|> mapMaybe (\(paramName, paramValue) -> paramValue)
|> map cs
-- ingredients = ["milk", "ingredients"]
Run Code Online (Sandbox Code Playgroud)
然后像这样在控制器中使用它:
module Application.Helper.Controller
( ...
, paramList -- Don't forget the export :)
)
paramList name = allParams
|> filter (\(paramName, paramValue) -> paramName == name)
|> mapMaybe (\(paramName, paramValue) -> paramValue)
|> map cs
Run Code Online (Sandbox Code Playgroud)
中的所有功能Application.Helper.Controller在我们的控制器中自动可用。
| 归档时间: |
|
| 查看次数: |
133 次 |
| 最近记录: |