ClojureScript / OM:从另一个组件更新组件的状态 - 或:使用全局状态

时间:2015-12-28 19:38:16

标签: clojurescript om

我使用非常简单的应用程序开始使用om和ClojureScript。

我的全球应用状态如下:

(def app-state (atom {:animals [ {:name "dog" :img "pic01.jpg"}
                                 {:name "cat" :img "pic02.jpg"}
                                 {:name "mouse" :img "pic03.jpg"}
                                 {:name "camel" :img "pic04.jpg"}]}))

vector" animals"中每个哈希映射的name属性。通过我调用的" menu"的om组件呈现为HTML列表结构(例如LI-tag)。每个条目由另一个名为" entry"的组件呈现。 (例如,作为UL元素)。 每当用户悬停其中一个列表条目时,条目的外观就会改变(可能是背景改变)。我在入口组件中捕获这些当前状态,我通过om / IInitState初始化。

到目前为止这是有效的。现在我想添加另一个组件,名为" display"。只要用户点击列表中的条目,它就应该能够显示与全局状态中的动物名称相关联的图像。我问自己,解决这个问题的最佳方法是什么。

我看到两种可能性:

在"显示"中保持本地状态组件,由"条目"中的onClick事件更新。零件。 在这里,我的问题是:如何从另一个组件更新组件的状态?

或者在全局状态中引入另一个属性,可能称为:" active_section",它由条目组件中的onClick事件更新,并由"显示"零件。但那有必要吗?

2 个答案:

答案 0 :(得分:2)

不确定我100%理解你的要求,但是我会花2美分。

一般来说,我会避免涉及一个组件以某种方式更新另一个组件中的本地状态的设计。这会在组件之间产生紧密耦合,这可能不是你真正想要的。最好设计/开发您的组件,以便他们对其他组件的知识尽可能少。

基于反应的应用程序的最佳方法是将您的状态保持在全局状态原子中。在这种情况下,我会有一个组件(菜单组件?)在全局状态中设置:visible或:current属性值,表示当前动物。您的其他组件将根据此属性设置为true的条目呈现动物。

这样做的另一个好处是,如果您决定添加需要对当前“动物”进行操作的其他组件,它也可以使用该信息。

保持可能在一个地方触发DOM渲染的所有状态更改也可以使调试更容易。另外,请查看om-next(有quick start教程),因为它有一种新的设置/设置状态的方法,它可以使事情比旧的“光标”方法简单得多。

答案 1 :(得分:1)

我使用两种不同的方法。第一个是组件"广播"它是一种消息。例如,我有一个日历组件,"广播"它"当前日期"。当有人点击其他日期时,它会广播该新日期。任何组件都可以监听该消息并在必要时自行更新。

我的第二种方法是让组件向另一个"广播消息"零件。它通过广播"类型"另一个组件正在侦听的消息。例如,我有一个想要编辑客户的组件。它广播"客户"它希望被编辑为"客户编辑组件"。 "客户编辑组件"决定是否可以显示客户并处理编辑。如果它决定保存更改,那么" save"消息是广播的。列出"保存"消息处理请求并广播" save"的结果。显示客户信息的组件处理"更新"客户留言并显示更改。

唯一的耦合是消息总线和消息之间的耦合。所有这些都是使用core.async实现的。

您应该事先决定的问题是是否有多个公共汽车(频道)。另一个问题是组件需要短路未指向它们的消息。

我有一个特殊的组件,它监听所有消息以进行调试。

我会小心将所有全局数据直接绑定到组件。我更喜欢将全局数据视为数据库,而不是组件的内部数据。