2016-10-31 40 views
1

我有一个游戏的UI与各种组件,其中一些可以点击突出显示('积极'组件)。目前,每个组件的状态都可以突出显示Bool。但是,我想强制一次只突出一个组件 - 因此,如果点击某个组件,则当前突出显示的任何其他组件都必须更新为未突出显示。如何在Elm 0.17中一次突出显示单个组件?

要做到这一点的一种方法是让共同的祖先将一些消息广播给所有的孩子,并且每个组件都可以处理这个消息并将其自动关闭 - 但是这看起来相当复杂和浪费。可能有1000个组件,只有两个正在改变(一个突出显示,一个突出显示),为什么我应该发送并处理1000条消息?

有没有更好的方法?

注意:这与Elm 0.17: How to subscribe to sibling/nested component changes非常相似。我认为有一点不同的是,在这个问题中,只有少量的相关组件,而当其他组件发生变化时,总是发生变化。就我而言,在整个模型中的不同位置有很多组件,并且当其中一个更改很少时,或者其他更改都不会更改。

回答

1

Elm运行时和虚拟DOM引擎将确保只有被更改的组件才会被重新渲染。所以我不会太担心发送消息给1,000个组件。

你的情况:

  • 您的更新功能将改变只有2组件设置/取消激活状态/只发送邮件至2个组件。
  • 您的视图函数将始终运行所有1000个组件
  • Elm的虚拟DOM区别引擎将只呈现更改为DOM的2个组件。

当与内部状态的组件的工作,你会需要的是:

  • 每个部件需要知道它是否处于活动状态。可能是Bool。 可能是组件的model中的字段。
  • 全球model需要知道哪些组件是活动的。可能带有Maybe Int,其中Int是活动组件的ID。
  • 当一个组件被点击以使其自身处于活动状态时,它将向应该包含其ID的父对象发送一些Msg,所以父级知道哪个组件现在处于活动状态。 (请参阅example here以了解其工作原理)
  • 父代的update函数会在其获取消息元素时更新其自己的model中的活动元素。并且父级更新1或2个子组件来更改这些组件的活动标志。
5

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

相反,如果不在组件中存储突出显示的状态,只能在主模型中存储。然后组件的视图函数将采用额外的布尔“突出显示”参数。

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

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

相关问题