ReflexFRP:如何在按钮单击时从textInput设置按钮文本

时间:2017-01-08 21:57:46

标签: haskell frp reflex

我有一个简单的小部件,应该从给定的文本输入字段设置按钮的“文本”。

虽然我设法做了一个简单明了的功能

buttonWidget :: MonadWidget t m => m ()
buttonWidget = do
  send  <- button "clear"
  input <- textInput $ def & setValue .~ fmap (const "") send
  return ()

我没有设置按钮标签 - 下面的代码编译

buttonWidget :: MonadWidget t m => m ()
buttonWidget = do
  rec send  <- button val
      input <- textInput $ def & setValue .~ fmap (const "") send
      val   <- sample $ current $ view textInput_value input
  return ()

但是查看输出index.html - 我只得到一个带有控制台错误消息的白页:

  

rts.js:7313 thread blocked indefinitely in an MVar operation

2 个答案:

答案 0 :(得分:3)

reflex-dom中的香草按钮似乎不支持动态标签;

solutionWidget :: MonadWidget t m => m ()
solutionWidget = do
  rec send  <- dynButton dyn
      input <- textInput $ def & setValue .~ fmap (const "") send
      dyn <- holdDyn "click button to set text below"
                     (tag (current $ view textInput_value input) send)
  return ()

我们需要定义以下内容:

dynButton :: MonadWidget t m => Dynamic t Text -> m (Event t ())
dynButton s = do
  (e, _) <- elAttr' "button" (Map.singleton "type" "button") $ dynText s
  return $ domEvent Click e

答案 1 :(得分:3)

这里发生的是button接受字符串(或文本,取决于版本),此字符串取决于文本输入的值,而文本输入的值又取决于按钮产生的事件。现在,事件网络中通常类似的循环就好了,但是在这里你需要对输入值进行采样以获得之前的文本甚至呈现按钮(因为它需要将该文本呈现给DOM)。

以下代码(用hsnippet编写,更老的反射 - dom和简化(无镜头))显示了如何定义一个“按钮”帮助器,它不需要在输入文本实现之前实现写到DOM:

app :: MonadWidget t m => App t m ()
app = do
  rec send  <- button' $ _textInput_value input
      input <- textInput $ def { _textInputConfig_setValue = fmap (const "") send }
  return ()

button' :: MonadWidget t m => Dynamic t String -> m (Event t ())
button' s = do
  (e, _) <- elAttr' "button" (M.singleton "type" "button") $ dynText s
  return $ domEvent Click e