如何在Elm 0.17中一次突出显示单个组件?

时间:2016-10-31 05:47:36

标签: elm

我有一个包含各种组件的游戏UI,其中一些可以点击以突出显示(“活动”组件)。这是通过让Bool处于可以突出显示的每个组件的状态来完成的。但是,我想强制执行一次只能突出显示一个组件 - 因此,如果点击了某些内容,则当前突出显示的任何内容都必须更新为不突出显示。

这样做的一种方法是让共同的祖先向所有不同的孩子广播一些消息,并且每个组件都可以处理此消息并自行关闭 - 但这看起来非常复杂和浪费。可能有1000个组件,只有两个组件正在更改(一个用于突出显示,一个用于非高亮显示),那么我为什么要发送和处理1000条消息呢?

有更好的方法吗?

注意:这似乎与Elm 0.17: How to subscribe to sibling/nested component changes非常相似。我认为一个不同之处在于,在那个问题中存在少量相关组件,当一个组件发生变化时,另一个组件会发生变化。在我的情况下,整个模型中的不同位置有许多组件,当一个变化很少或其他任何一个都不会改变时。

2 个答案:

答案 0 :(得分:5)

是的,可能有更好的方法。建议不要在应用程序的多个位置复制某些状态,因为这会导致同步问题并使调试更加困难。

相反,最好不要将突出显示的状态存储在组件中,而只存储在主模型中。然后组件的视图函数将采用另一个布尔“突出显示”参数。

要将突出显示的状态存储在主模型中,您可以为每个组件指定一个ID并将highlighted : Maybe ID添加到模型中。

因此,您只需将点击消息从子节点传播到父节点,而不是从父节点传播到子节点。

答案 1 :(得分:1)

Elm运行时和虚拟DOM引擎将确保仅重新呈现更改的组件。因此,我不会过于担心向1,000个组件发送消息。

在你的情况下:

  • 您的更新功能只会更改2个组件来设置/取消设置活动状态/仅将消息发送到2个组件。
  • 您的查看功能将始终针对所有1000个组件
  • 运行
  • Elm的虚拟DOM diff引擎只会渲染更改为DOM的2个组件。

使用具有内部状态的组件时,您需要的是:

  • 每个组件都需要知道它是否处于活动状态。可能是Bool。 可以是组件model
  • 中的字段
  • 全局model需要知道哪些组件是活动的。可能使用Maybe Int,其中Int是活动组件的ID。
  • 当单击某个组件使其自身处于活动状态时,它会向父级发送一些Msg,其中应包含其ID,因此父级知道哪个组件现在处于活动状态。 (参见example here这可行的方法)
  • 父级update函数在获取消息元素时更新其自身model中的活动元素。父级更新1或2子组件以更改这些组件的活动标志。