首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何有效地对Reflex.Dynamic内部的值进行分支?

如何有效地对Reflex.Dynamic内部的值进行分支?
EN

Stack Overflow用户
提问于 2016-11-09 06:05:10
回答 1查看 224关注 0票数 3

假设我有一些在某个后端系统上维护的应用程序状态。它看起来像这样

代码语言:javascript
复制
data MyState = State1 MyState1 | State2 MyState2

data MyState1 = MyState1 { ms1_text :: Text, ms1_int :: Int }
data MyState2 = MyState2 { ms2_bool :: Bool, ms2_maybe_char :: Maybe Char }

我还有一个从后端系统获取最新状态的函数

代码语言:javascript
复制
getLatestState :: IO MyState

我非常确定我可以通过反复查询后端来弄清楚如何将其打包到动态中,这样我就有了

代码语言:javascript
复制
dynMyState :: MonadWidget t m => Dynamic t MyState

我想将其呈现为html。我希望数据结构的每个部分都呈现到一个div中。然而,根本不应该呈现不存在的东西--因此,当ms2_maybe_charNothing时,不应该为其提供div,而当MyStateState1时,则不应该为State2提供div。

为了清楚起见,有几个例子:

代码语言:javascript
复制
State1 (MyState1 "foo" 3)

变成了

代码语言:javascript
复制
<div class=MyState1>
    <div>foo</div>
    <div>3</div>
</div>

代码语言:javascript
复制
State2 (MyState2 False Nothing)

变成了

代码语言:javascript
复制
<div class=MyState2>
    <div>False</div>
</div>

理想情况下,只有在必要时才应该修改DOM的每个部分-因此,如果ms2_maybe_charNothing更改为Just 'a',则需要创建一个新的div。或者,如果ms1_text"foo"更改为"bar",那么我们需要在DOM中更改该字符串。但是,更改ms1_text不应导致重绘同级节点或父节点。

我应该如何组织我的代码?考虑到getLatestState应用编程接口作为构建块,这有可能实现吗?我试图在单个Dynamic值的基础上构建Reflex,这是不是完全错过了Reflex的要点,我需要重新考虑我的方法?

特别是,第一个障碍是我不能轻松地检查动态以了解它是包含State1还是State2。我可能会在这里使用dynwidgetHold,并在dynMyStatefmap一个函数,该函数可以将状态视为一个简单的值,并生成一个绘制整个内容的m ()操作。但是,我失去了所有的共享--每次状态改变时,整个UI都会从头开始重新绘制。

注意:这是How can I branch on the value inside a Reflex Dynamic?的一个更详细的后续问题。这个问题的不同之处/更清楚的是,它还希望不会丢失检查值中所有内容的有效更新。感谢在这个问题上提供帮助的每一个人!

EN

回答 1

Stack Overflow用户

发布于 2017-03-06 10:07:50

答案取决于你的目标和需求到底是什么。如果你想要最好的dom共享,从两个独立的函数renderState1renderState2派生而来,我认为应该使用virtual-dom

但实际上,这听起来像是您希望对添加到DOM的内容有一些精确的控制。

如果你手中有修改过的renderState1renderState2版本,每个版本都有一个Maybe State1Maybe State2参数,那么你可以做一件简单的事情,那就是构建一对这样的动态可能,并使用css属性隐藏其中之一:

代码语言:javascript
复制
let mState1 = (\c -> case c of
                  s@(State1 _ _) -> Just s
                  _              -> Nothing
              ) <$> dynMyState
    mState2 = (\c -> case c of
                  s@(State2 _ _ _) -> Just s
                  _                -> Nothing
    nothingHider a m =
       let atr = bool mempty ("style" =: "displayNone") . isJust <$> a
       in  elDynAttr "div" atr (m a)

nothingHider mState1 renderMaybeState1
nothingHider mState2 renderMaybeState2

如果你使用derive Prisms,那么很多尴尬都可以摆脱。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40497229

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档