如何在Reflex Dynamic中分支值?

ajp*_*ajp 2 haskell reflex

在最简单的情况下,假设我有一个Dynamic t Bool,当值为true时,我想要一个空div存在,当值为false时,我不希望有任何dom元素.

稍微更一般,如果我有一个Dynamic t (Either MyA MyB),并且我的函数知道如何渲染给定a Dynamic t MyA或a Dynamic t MyB,如何调用相应的函数来渲染?

Bar*_*osz 5

如果您需要切换小部件,您可能需要以下方法之一:

dyn :: MonadWidget t m => Dynamic t (m a) -> m (Event t a) Source
Run Code Online (Sandbox Code Playgroud)

要么

widgetHold :: MonadWidget t m => m a -> Event t (m a) -> m (Dynamic t a)
Run Code Online (Sandbox Code Playgroud)

既然你已经提到过你手头的动态,我们将使用dyn:

app = do
  switched <- button "Alternate!"
  flag <- foldDyn ($) False (not <$ switched) -- just to have some Dynamic t Bool
  let w = myWidget <$> flag
  void $ dyn w

myWidget :: MonadWidget t m => Bool -> m ()
myWidget False = blank
myWidget True = el "div" $ blank
Run Code Online (Sandbox Code Playgroud)

基本规则是,由于Reflex的高阶性质,如果你想换掉一些东西,你需要有一个Event/Dynamic,它将一个小部件作为一个值.这就是为什么dyn需要Dynamic t (m a)作为它的参数(并且适当地widgetHold采用Event t (m a).这就是为什么我们已经映射Dynamic t Bool到具有将我们的小部件构建动作作为值的动态.

值得一提的是,动态/ widgetHold都不会进行虚拟dom/diffing来加速渲染.通过反射,您可以更明确地了解更新内容(动态/事件文本可以直接影响节点文本,而无需重新呈现整个节点),您应该利用它.如果没有,那么将交换大部分页面,并且它可以产生显着的性能损失.