我想要做的是设置字段,当它们处于焦点时显示详细信息,而当它们不处于焦点时显示摘要。例如。
A)。当它失去焦点(变得模糊?)时,我将值保存在(状态?)映射中,然后将该值更改为旧值的函数(即汇总值)
b).当它获得焦点时 - 我用我在地图中保存的旧值替换摘要值
我不知道如何做到这一点,但我想我可能需要一个状态 monad 和 UI monad。我的尝试是:
renderField :: Map->Int->UI (Element, Map)
renderField vs ix = do
input <- UI.input
on UI.blur input $ \_ -> void $ do
fieldValue <- get value input
let newVs = insert ix fieldValue vs
return input # set UI.value (calcNewValue fieldValue)
on UI.focus input $ \_ -> void $ do
let savedValue = findWithDefault "" ix vs
return input # set UI.value savedValue
return (input, newVs)
但我无法让这张地图工作 - 因为它需要跟踪所有的调用....我想它应该是 State monad 或其他东西?
Thanks.
N
事实上,您需要跟踪状态。
然而,通常的模式s -> (a,s)
(状态单子)在这里不适用,因为您正在使用回调函数。对于这些,您需要不同的模式。
在传统的命令式风格中,人们会在这里使用可变变量,例如IORef
。请注意,不再需要跟踪索引——您可以考虑一个IORef
作为大型可变映射中的索引。
renderField :: UI Element
renderField = do
input <- UI.input
state <- liftIO $ newIORef
on UI.blur input $ \_ -> do
fieldValue <- get value input
liftIO $ writeIORef state fieldValue
element input # set UI.value (calcNewValue fieldValue)
on UI.focus input $ \_ -> do
savedValue <- liftIO $ readIORef state
element input # set UI.value savedValue
return input
或者,您也可以在 Threepenny 中使用函数反应式编程 (FRP)。请注意,该 API 仍处于初步阶段,以下代码具体用于threepenny-gui
版本0.4.*
:
renderField :: UI Element
renderField = do
input <- UI.input
bValueUser <- stepper "" $ UI.valueChange input
bState <- stepper "" $ bValueUser <@ UI.blur input
bValue <- stepper "" $ fmap head $ unions
[ (calcNewValue <$> bValueUser) <@ UI.blur input
, bState <@ UI.focus input
]
element input # sink UI.value bValue
同样,这段代码中仍然存在一些微妙之处和缺陷,但这是我想要的总体方向。有关 FRP 及其如何应用于 GUI 开发的一些初步信息可以在文档 https://github.com/HeinrichApfelmus/threepenny-gui/blob/master/doc/design-widgets.md.
我的建议是使用熟悉的解决方案(IORef
)当您需要快速完成某件事时,当您有充足的空闲时间时,探索 FRP 解决方案。这示例代码 https://github.com/HeinrichApfelmus/threepenny-gui/tree/master/samples主要采用FRP样式。
(披露:我是《三便士》的作者。)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)