【问题标题】:ClojureScript / OM: update a component's state from another component - or: working with global stateClojureScript / OM:从另一个组件更新组件的状态 - 或者:使用全局状态
【发布时间】:2015-12-30 02:50:38
【问题描述】:

我正在通过一个非常简单的应用程序开始使用 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"}]}))

向量“animals”中每个散列映射的 name 属性由我称为“menu”的 om 组件呈现为 HTML 列表结构(例如 LI-tag)。每个条目都由另一个称为“条目”的组件呈现。 (例如,作为 UL 元素)。 每当用户将鼠标悬停在列表条目之一时,条目的外观就会发生变化(可能背景会发生变化)。我在入口组件中捕获这些当前状态,并通过 om/IInitState 对其进行初始化。

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

我看到了两种可能性:

在“display”组件中保持本地状态,该状态由“entry”组件的 onClick 事件更新。 在这里,我的问题是:如何从另一个组件更新组件的状态?

或者在全局状态中引入另一个属性,可能叫做:“active_section”,由entry组件中的onClick事件更新,由“display”组件读取。但有必要吗?

【问题讨论】:

  • 好像你刚开始使用 Om,就在 Om/Next 正在替换它的时候。

标签: clojurescript om


【解决方案1】:

我不确定我是否 100% 了解您的要求,但我会投入 2 美分。

一般来说,我会避免涉及一个组件以某种方式更新另一个组件中的本地状态的设计。这会在组件之间创建紧密耦合,这可能不是您真正想要的。设计/开发您的组件要好得多,这样他们对其他组件的了解就更少(如果有的话)。

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

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

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

【讨论】:

  • 感谢蒂姆,这正是我正在寻找的考虑因素。非常有帮助。 om/next 将是我检查的 next 东西。而是一步一步来。
【解决方案2】:

我使用两种不同的方法。第一个是让组件“广播”它的状态作为消息。例如,我有一个“广播”它是“当前日期”的日历组件。当有人点击不同的日期时,它会广播该新日期。任何组件都可以侦听该消息并根据需要自行更新。

我的第二种方法是让组件向“另一个”组件广播消息。它通过广播其他组件正在侦听的“类型”消息来做到这一点。例如,我有一个想要编辑客户的组件。它将想要编辑的“客户”广播到“客户编辑组件”。 “客户编辑组件”决定它是否可以显示客户并处理编辑。如果它决定保存更改,则广播“保存”消息。 “保存”消息列表处理请求并广播“保存”的结果。显示客户信息的组件处理“更新的”客户消息并显示更改。

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

您应该预先决定的问题是是否拥有多个总线(通道)。另一个问题是组件需要将未定向到它们的消息短路。

我有一个特殊的组件可以侦听所有消息以进行调试。

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

【讨论】:

    猜你喜欢
    • 2020-07-01
    • 1970-01-01
    • 2021-10-18
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 2019-12-11
    相关资源
    最近更新 更多