老问题,但我今天需要这个,所以不妨将它发布给遇到同样问题的其他人。
基本上,正如迈克尔建议的那样,我们可以将数据序列化到会话中。这样做很棘手,而且把它变成一个表格更棘手。我不得不撕掉它们postEnv
,postHelper
因为Yesod.Form.Functions
它们没有被导出,但需要这样做。
然后,您可以setLastInvalidPost
在重定向之前在您的处理程序中使用,然后generateFormFromLastPost
在目标处理程序中使用。
请注意,使用类似的东西Data.Serialize
进行序列化可能会更好;但是,Show
/Read
实例足以满足我的需求(而且更简单)。
这是好东西。如果你想要一个完整的工作片段,你可以查看我的 gist。
-- Create a form from last post data in the session if exists, otherwise create a blank form.
generateFormFromLastPost :: (RenderMessage (HandlerSite m) FormMessage, MonadHandler m) =>
(Markup -> MForm m (FormResult a, xml)) -> m (xml, Enctype)
generateFormFromLastPost form = do
env <- getLastInvalidPost
case env of
Nothing -> generateFormPost form
Just _ -> first snd <$> postHelper form env
lastInvalidPostSessionKey :: Text
lastInvalidPostSessionKey = "lastInvalidPost"
-- Sets the post data retreived from postEnv, ignoring the FileEnv.
setLastInvalidPost :: MonadHandler m => Maybe (Env, FileEnv) -> m ()
setLastInvalidPost Nothing = return ()
setLastInvalidPost (Just (env, _)) = sessionSetter lastInvalidPostSessionKey env
-- Retrieves the previous post data to be passed to postHelper.
getLastInvalidPost :: MonadHandler m => m (Maybe (Env, FileEnv))
getLastInvalidPost = do
result <- sessionGetter lastInvalidPostSessionKey
return $ case result of
Nothing -> Nothing
Just env -> Just (env, Map.fromList [])
sessionSetter :: (MonadHandler m, Show a) => Text -> a -> m ()
sessionSetter key = setSession key . pack . show
sessionGetter :: (MonadHandler m, Read b) => Text -> m (Maybe b)
sessionGetter key = do
m <- lookupSession key
return $ readMaybe . unpack =<< m