この小さなプログラムの目的は、3 つのボタンを表示することです。3 番目のボタンのラベルは最初は「0」で、その後は最後にクリックされたボタンのインデックスになります。今のところ、ボタンの数と他のボタンのラベルは一定です。
この自己完結型のファイルを ghcjs でコンパイルし、Main.jsexe/index.html をブラウザーにロードすると、2 つの traceDyns がループで起動し、両方とも値が常に 0 であることがわかります。私が理解している限り、何も起こらないはずです。 _el_clicked がシステムの残りの部分にフィードするため、ボタンがクリックされるまで。
また、mapDyn (fst . head . Map.toList)
選択したボタンのインデックスを抽出するために使用していることに注意してください。これが正しいかどうかはわかりませんが、どちらにしても無限ループの原因はわかりません。
{-# LANGUAGE RecursiveDo #-}
module Main where
import Reflex
import Reflex.Dom
import qualified Data.Map as Map
dynButton
:: MonadWidget t m
=> Dynamic t String
-> m (Event t ())
dynButton s = do
(e, _) <- el' "button" $ dynText s
return $ _el_clicked e
-- widget that takes dynamic list of strings
-- and displays a button for each, returning
-- an event of chosen button's index
listChoiceWidget
:: MonadWidget t m
=> Dynamic t [String]
-> m (Event t Int)
listChoiceWidget choices = el "div" $ do
asMap <- mapDyn (Map.fromList . zip [(0::Int)..]) choices
evs <- listWithKey asMap (\_ s -> dynButton s)
k <- mapDyn (fst . head . Map.toList) evs
return $ updated (traceDyn "k" k)
options :: MonadWidget t m => Dynamic t Int -> m (Dynamic t [String])
options foo = do
mapDyn (\x -> ["a", "b", show x]) foo
main :: IO ()
main = mainWidget $ el "div" $ do
rec n <- listChoiceWidget o
o <- options foo
foo <- holdDyn 0 n
display (traceDyn "foo" foo)