私は Yesod を使用して Ajax アプリを作成しています (jQuery を使用していますが、私の質問にはそれほど重要ではないと思います)。基本的に、私が望むのは、XMLHttpRequest ヘッダーが送信されたかどうかに応じて、サーバーが同じデータの異なる表現を送信することです。(これらすべてのポイントは、 history.jsのような JavaScript ライブラリを使用することです
特に、次のようなルートが必要です。
/picture/#PictureId GET
これは、XHR ヘッダーなしでアクセスすると、デフォルト レイアウトに移動することによって処理されます。さらに良いことに、最終的にデフォルト レイアウトでラップされるウィジェットによって処理され、XHR リクエストによってアクセスされると、HTML 表現を送信するだけです。ウィジェット。
これにどのようにアプローチすればよいですか?カスタムの defaultLayout のような関数を作成して、ウィジェットをロジックでラップできると思います。それは賢明ですか、それともより良いアプローチがありますか?
編集: Yesod クラスの defaultLayout メソッドを次のようにオーバーライドすることにしました。
defaultLayout widget = do
req <- waiRequest
let reqwith = lookup "X-Requested-With" $ requestHeaders req
when (maybe False (== "XMLHttpRequest") reqwith) $ do
(PageContent _ _ w) <- widgetToPageContent widget
giveUrlRenderer $ [hamlet| ^{w} |]
...
しかし、今はタイプエラーが発生しています。よくわかりません
Couldn't match type `blaze-markup-0.5.1.5:Text.Blaze.Internal.MarkupM ()'
with `()'
Expected type: HandlerT App IO ()
Actual type: HandlerT
App IO (blaze-markup-0.5.1.5:Text.Blaze.Internal.MarkupM ())