这个小程序的目的是显示三个按钮,第三个按钮的标签最初是“0”,然后是最后点击按钮的索引。现在按钮的数量和其他按钮的标签是不变的。
当我用 ghcjs 编译这个自包含文件并在浏览器中加载 Main.jsexe/index.html 时,我可以看到两个 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)