- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这个小程序的目的是显示三个按钮,第三个按钮的标签最初是“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)
最佳答案
看起来您的 listChoiceWidget 代码正在丢弃由 dynButton 构造的点击事件。listWithKey
返回 m (Dynamic t (Map k a))
.在您的情况下, key 类型为 Int
并且值为 Event t ()
(由 dynButton 制作)。
在这一行:
k <- mapDyn (fst . head . Map.toList) evs
Dynamic t (Map Int (Event t ()))
成
Dynamic t Int
但是,至关重要的是,当点击事件触发时,您并没有这样做。这条线映射到
evs
并生成一个 Dynamic ,该动态将始终包含 Int 到事件的映射中的第一个键,无论事件是否已触发。它将始终是包含 Int 0 的 Dynamic。
main
供稿foo
其初始值为 0 到 options
listChoiceWidget
接收新选项并更新列表 foo
接收来自 listChoiceWidget
的 key 更新事件Event t ()
,但你真正需要的是
Event t Int
,这样当一个事件触发时,你就可以知道它来自哪个按钮。
evs' <- mapDyn (Map.mapWithKey (\k e -> fmap (const k) e)) evs
evs'
有类型
Dynamic t (Map Int (Event t Int))
.接下来,我们需要某种方式来组合我们的事件,以便我们有一个使用最近点击的按钮的键触发的事件。
dynEv <- mapDyn (leftmost . Map.elems . Map.mapWithKey (\k e -> fmap (const k) e)) evs
dynEv
现在有类型
Dynamic t (Event t Int)
. Map 的键已经被烘焙到事件中,所以我们不再需要它们了。
Map.elems
将我们的事件 map 转换为事件列表,然后
leftmost
允许您将一系列事件合并为一个事件。
leftmost
:“创建一个新事件,如果列表中的至少一个事件发生,则该事件发生。如果同时发生多个事件,则使用给定函数从左侧折叠它们。”
Dynamic t (Event t Int)
成
Event t Int
.我们将使用
switch
,这需要一个
Behavior t (Event t a)
并返回
Event t a
.因此,以下行将导致
Event t Int
.
switch (current dynEv)
current
提取
Behavior
的
Dynamic
, 和
switch
创建“一个将在当前选择的输入事件发生时发生的事件”。
listChoiceWidget
代码。我已经包含了内联类型注释,所以你需要
ScopedTypeVariables
启用编译此代码的语言扩展(或者您可以删除注释)。
listChoiceWidget
:: forall t m. MonadWidget t m
=> Dynamic t [String]
-> m (Event t Int)
listChoiceWidget choices = el "div" $ do
asMap <- mapDyn (Map.fromList . zip [(0::Int)..]) choices
evs :: Dynamic t (Map.Map Int (Event t ())) <- listWithKey asMap (\_ s -> dynButton s)
dynEv :: Dynamic t (Event t Int) <- mapDyn (leftmost . Map.elems . Map.mapWithKey (\k e -> fmap (const k) e)) evs
return $ switch (current dynEv)
关于haskell - 为什么此 Reflex 代码会导致 Dynamics 以相同的值无限期触发?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30885883/
我正在对用 Java 语言编写的程序进行逆向工程。到目前为止,一切都很有意义,除了一段我根本无法理解的代码。该程序本身是流行游戏Minecraft的服务器,尽管我强烈认为这个问题与其本身无关。让我向您
在 Python 的时间模块中,有一个 sleep() 函数,可以让 Python 等待 x 秒后再继续执行程序。有没有办法无限期地执行此操作直到满足条件?例如: while True: ti
我有一个 php 脚本,它可能需要 2 到 10 分钟才能执行。它从网络上获取信息,因此它的时间取决于许多其他事物的通话速度。 我曾经每 15 分钟在 cron 上运行一次脚本,但有时只需要 2 分钟
我运行 Mac OSX 10.7 和 Xcode 4.2.1,一切都很好,直到几个小时前,当我尝试运行模拟器时,我的 xcode 突然挂起!这是发生了什么 代码构建成功,但它无限期地显示“Attach
我目前正在阅读 Ivor Horton 的 Beginning C。无论如何,我不确定的 for 在继续之前打印了我的 printf 语句两次。我确定我做错了什么,但我直接从书中复制了代码。如果重要的
我正在使用一个在下面设置 session 变量/cookie 的登录系统。 Chrome,它可以让你轻松地查看你的 cookie,显然将其标记为“当我关闭浏览器时”过期的 PHPSESSID。果然,当
任务是:尝试使用最基本的形式(如“ping 8.8.8.8”)在 python 中发送 ping。一段时间后终止 ping 命令(在终端中,将执行 Ctrl+C)并获得其输出。显示 ping 统计信息
我是一名优秀的程序员,十分优秀!