2016-08-10 150 views
2

我想寫沒有任何哈姆雷特部件的yesod應用程序。我的問題是關於表單:我可以使用Applicative生成表單,但我不能直接在我的代碼中使用它。如何在Yesod中使用blaze代碼構建小部件?

這裏是一個小村莊的版本例如:

-- actual form example 
userForm :: Form User 
userForm = renderDivs $ User 
    <$> areq textField "Login" Nothing 
-- usage example 
getPageR :: Handler Html 
getPageR = do 
    ((_, widget), enctype') <- runFormGet userForm 
    defaultLayout [whamlet| 
       <form method=post [email protected]{PageR} enctype=#{enctype'}> 
       ^{widget} -- This widget include. 
       <button>Submit|] 

但我怎麼可以重寫它而不哈姆萊特?我當前的代碼是這樣的:

getPageR = do 
    ((_, widget), enctype') <- runFormGet userForm 
    defaultLayout $ do 
    toWidgetBody $ \render -> do 
     H.div ! A.id "form" $ do 
     H.form ! A.method "post" ! A.action (action' render) ! A.enctype (enct' enctype) $ "" 
     -- widget include? 
     H.button "Submit!" 
    where 
    action' = \render -> toValue $! render (PageR) [] 
    enct' = toValue . renderHtml . toHtml 

Obvously,閃耀代碼的類型爲HTML,但是用戶窗體類型是一個小部件,因此它不能連接。我只能在toWidgetBody函數後添加小部件,但後來形式畢竟會是內容。有沒有一種方法可以將火焰組合器中的表單(通過渲染爲Html,或許?)包含進去?沒有小組件^{widget}構造?

回答

2

使用widgetToPageContent函數。

然後通過調用pageBody並應用render函數得到Html

getPageR :: Handler Html -- same as: HandlerT App IO Html 
getPageR = do 
    ((_, widget), enctype') <- runFormGet sampleForm 
    content <- widgetToPageContent widget 
    defaultLayout $ do 
    toWidgetBody $ \render -> do 
     H.div ! A.id "form" $ do 
     H.form ! A.method "post" ! A.action (action' render) 
           ! A.enctype (enct' enctype') $ "" 
     pageBody content render 
     H.button "Submit!" 
    where 
    action' = \render -> toValue $! render (PageR) [] 
    enct' = toValue . renderHtml . toHtml 
    (!) = (H.!) 
    toValue = H.toValue 
+0

如果我想使用monadic形式而不是applicative,是否可以將FieldView擴展爲Html,從而也可以在小部件定義中使用它? – Takao

+0

請用適當的代碼示例爲此打開一個新問題 - 謝謝。 – ErikR

相關問題