ReflexFRP: Как установить текст кнопки из textInput при нажатии кнопки

У меня есть простой виджет, который должен установить "текст" кнопки из данного поля ввода текста.

Пока мне удалось сделать простой понятный функционал

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 ответа

Решение

Что здесь происходит, так это button принимает строку (или текст, в зависимости от версии), и эта строка зависит от значения ввода текста, которое, в свою очередь, зависит от события, создаваемого кнопкой. Теперь обычно подобные циклы в сети событий просто хороши, но здесь вам нужно сэмплировать входное значение, чтобы получить текст еще до того, как кнопка будет отрисована (потому что этот текст нужен для отображения в DOM).

Следующий код (написанный на hsnippet, более старом reflex-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

Кажется, что ванильные кнопки в 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
Другие вопросы по тегам