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