如何在 Yesod 中为 selectField 构建预选选项?
How to build a pre-selected option for a selectField in Yesod?
(This was asked before but it has no answers).
我在数据库中有一个国家列表:
share [mkPersist sqlSettings] [persistLowerCase|
Country
name Text
UniqueCountryName name
deriving Show
|]
而且我可以向 select 其中之一展示表格:
countries = do
rows <- runDB $ selectList [] [Asc CountryName]
optionsPairs $ map (\ r -> (countryName $ entityVal r, entityKey r)) rows
surveyForm :: Html -> MForm Handler (FormResult SurveyAnswerSet, Widget)
surveyForm extra = do
(countryR, countryV) <- mreq (selectField countries) "" Nothing
我知道我应该将最后一行中的 Nothing
替换为所需的默认值,但我仍然不知道该怎么做。查看 mreq
and the optionsPairs
签名,我的想法是,在这种情况下,我应该提供默认国家/地区的 Maybe Option
,但我的尝试引发了太多类型错误,可能我离正确答案还很远。
Yesod 书中有一个示例使用似乎比我试图实现的更简单,所以我不确定如何推断它。
顺便说一句,我正在从数据库中获取默认国家/地区,因此我不需要对其内部 ID 进行硬编码:
defaultCountry = do
row <- runDB $ getBy $ UniqueCountryName $ countryName "United States"
(countryName $ entityVal row, entityKey row)
当我将它作为参数传递给 mreq
时,出现以下错误:
Couldn't match type ‘(,) Text’ with ‘HandlerFor site’
Expected type: HandlerFor site (Key record)
Actual type: (Text, Key record)
这是 defaultContry
函数 ((countryName $ entityVal row, entityKey row)
) 的最后一行。我知道我应该从一对中取出 Key record
并在 HandlerFor site
中取出 return 但同时我也得到:
Couldn't match expected type ‘Maybe (Key Country)’
with actual type ‘HandlerFor site0 (Key record0)’
在 (countryR, countryV) <- mreq (selectField countries) "" defaultCountry
行中。我将其解释为“你传递给我一个 HandlerFor site0 (Key record0)
但我只接受 Maybe (Key Country)
这似乎与第一个错误冲突......
在 (countryName $ entityVal row, entityKey row)
行中我还看到:
Couldn't match expected type ‘Entity Country’
with actual type ‘Maybe (Entity Country)’
在 row
参数中。我知道我应该从 Maybe
中提取 Entity Country
,但是如果我进行模式匹配并仅传递 Entity Country
(即:Just (Entity countryId country) -> (countryName $ entityVal (Entity countryId country), entityKey (Entity countryId country)
),我仍然会遇到第一个错误。
提前致谢。
好的,这看起来像是一些打字错误。第一个
Couldn't match type ‘(,) Text’ with ‘HandlerFor site’ Expected type: HandlerFor site (Key record) Actual type: (Text, Key record)
来自于在你的 do
符号中没有使用 return
来提升 monad 的值:
defaultCountry :: HandlerFor site (Text, Key record)
defaultCountry = do
row <- runDB $ getBy $ UniqueCountryName $ countryName "United States"
return (countryName $ entityVal row, entityKey row)
row
上的错误
Couldn't match expected type ‘Entity Country’ with actual type ‘Maybe (Entity Country)’
是因为是Maybe
,所以更正一下
defaultCountry :: HandlerFor site (Text, Key record)
defaultCountry = do
Just row <- runDB $ getBy $ UniqueCountryName $ countryName "United States"
return (countryName $ entityVal row, entityKey row)
现在 defaultCountry
是一个很好的 monad,您应该可以在其他代码中使用它。但是要小心第三个错误
Couldn't match expected type ‘Maybe (Key Country)’ with actual type ‘HandlerFor site0 (Key record0)’
您需要从 HandlerFor
monad 中解包值,然后将其重新包装在 Maybe
中
surveyForm :: Html -> MForm Handler (FormResult SurveyAnswerSet, Widget)
surveyForm extra = do
(defaultName, defaultKey) <- defaultCountry -- (defaultName, defaultKey) :: (Text, Key record)
(countryR, countryV) <- mreq (selectField countries) "" (Just defaultKey)
(This was asked before but it has no answers).
我在数据库中有一个国家列表:
share [mkPersist sqlSettings] [persistLowerCase|
Country
name Text
UniqueCountryName name
deriving Show
|]
而且我可以向 select 其中之一展示表格:
countries = do
rows <- runDB $ selectList [] [Asc CountryName]
optionsPairs $ map (\ r -> (countryName $ entityVal r, entityKey r)) rows
surveyForm :: Html -> MForm Handler (FormResult SurveyAnswerSet, Widget)
surveyForm extra = do
(countryR, countryV) <- mreq (selectField countries) "" Nothing
我知道我应该将最后一行中的 Nothing
替换为所需的默认值,但我仍然不知道该怎么做。查看 mreq
and the optionsPairs
签名,我的想法是,在这种情况下,我应该提供默认国家/地区的 Maybe Option
,但我的尝试引发了太多类型错误,可能我离正确答案还很远。
Yesod 书中有一个示例使用似乎比我试图实现的更简单,所以我不确定如何推断它。
顺便说一句,我正在从数据库中获取默认国家/地区,因此我不需要对其内部 ID 进行硬编码:
defaultCountry = do
row <- runDB $ getBy $ UniqueCountryName $ countryName "United States"
(countryName $ entityVal row, entityKey row)
当我将它作为参数传递给 mreq
时,出现以下错误:
Couldn't match type ‘(,) Text’ with ‘HandlerFor site’ Expected type: HandlerFor site (Key record) Actual type: (Text, Key record)
这是 defaultContry
函数 ((countryName $ entityVal row, entityKey row)
) 的最后一行。我知道我应该从一对中取出 Key record
并在 HandlerFor site
中取出 return 但同时我也得到:
Couldn't match expected type ‘Maybe (Key Country)’ with actual type ‘HandlerFor site0 (Key record0)’
在 (countryR, countryV) <- mreq (selectField countries) "" defaultCountry
行中。我将其解释为“你传递给我一个 HandlerFor site0 (Key record0)
但我只接受 Maybe (Key Country)
这似乎与第一个错误冲突......
在 (countryName $ entityVal row, entityKey row)
行中我还看到:
Couldn't match expected type ‘Entity Country’ with actual type ‘Maybe (Entity Country)’
在 row
参数中。我知道我应该从 Maybe
中提取 Entity Country
,但是如果我进行模式匹配并仅传递 Entity Country
(即:Just (Entity countryId country) -> (countryName $ entityVal (Entity countryId country), entityKey (Entity countryId country)
),我仍然会遇到第一个错误。
提前致谢。
好的,这看起来像是一些打字错误。第一个
Couldn't match type ‘(,) Text’ with ‘HandlerFor site’ Expected type: HandlerFor site (Key record) Actual type: (Text, Key record)
来自于在你的 do
符号中没有使用 return
来提升 monad 的值:
defaultCountry :: HandlerFor site (Text, Key record)
defaultCountry = do
row <- runDB $ getBy $ UniqueCountryName $ countryName "United States"
return (countryName $ entityVal row, entityKey row)
row
Couldn't match expected type ‘Entity Country’ with actual type ‘Maybe (Entity Country)’
是因为是Maybe
,所以更正一下
defaultCountry :: HandlerFor site (Text, Key record)
defaultCountry = do
Just row <- runDB $ getBy $ UniqueCountryName $ countryName "United States"
return (countryName $ entityVal row, entityKey row)
现在 defaultCountry
是一个很好的 monad,您应该可以在其他代码中使用它。但是要小心第三个错误
Couldn't match expected type ‘Maybe (Key Country)’ with actual type ‘HandlerFor site0 (Key record0)’
您需要从 HandlerFor
monad 中解包值,然后将其重新包装在 Maybe
surveyForm :: Html -> MForm Handler (FormResult SurveyAnswerSet, Widget)
surveyForm extra = do
(defaultName, defaultKey) <- defaultCountry -- (defaultName, defaultKey) :: (Text, Key record)
(countryR, countryV) <- mreq (selectField countries) "" (Just defaultKey)