直接从 "small" 可组合项访问业务逻辑层

Access business logic layer directly from a "small" composable

我将我的导航逻辑移至视图模型以将其与 导航组件 分离,例如 here.

由于 Composable 通常有 screen-level view model,这意味着该屏幕级别 Composable 的子 Composable 应该将一些事件传递给父级屏幕级别 Composable(通过回调),最终会将事件传递给视图模型。

然而,这将需要在导致事件的可组合项到父级屏幕级别 Composable.

之间的所有 Composable 之间传递事件。

我会说在大多数情况下没问题

但是,有一个例子并不好,一个小的(非屏幕级别)UI 元素 具有 业务逻辑它。该业务逻辑是应用程序的 cross cutting concern

想象一下在 Compose 中编写类似 Facebook 的应用程序。在各种不同的屏幕中,您可以看到用户的缩略图(好友列表、群组成员、帖子作者等)

每次您单击缩略图时,都会执行一段业务逻辑,最终将您导航到缩略图所有者的个人资料。 这显然是一个横切关注点,在每个屏幕的视图模型中实现它并将事件传递到屏幕级别 Composable 似乎会导致不必要的开销。

如何处理这种需要访问业务逻辑的“小”(非屏幕级别)Composable

对这么小的可组合项使用视图模型可能是一种选择,但感觉有点奇怪,因为视图模型似乎是 屏幕级别 可组合项的默认选择.

也许用CompositionLocals也可以实现,不过好像是excatly the discouraged case.

参考 "Thinking in Compose" 文章,我认为任何可组合项都不应直接与业务逻辑交互。每个可组合项都应该只呈现提供给它们的状态。事件应在屏幕的 ViewModel(或 high-level 屏幕可组合项)中传播和处理。

在您的 Facebook-like 应用程序 的情况下,单击缩略图是一个应该传播回屏幕 ViewModel 的事件。然后,根据您尝试实现的屏幕和逻辑,ViewModel 应该适当地处理事件和更改状态(或导航到另一个屏幕)。

可组合项应该可以在不同的屏幕上重复使用,并且不依赖于任何业务逻辑。如果您将小型可组合项与业务逻辑耦合,您将无法在其他屏幕上更改此可组合项的逻辑。

虽然这看起来不错,但假设您想在另一个屏幕上使用相同的可组合缩略图,并且当用户点击它时,您想要显示某种 AlertDialog。因为您将可组合项与导航事件耦合,所以您必须为此缩略图创建一个新的可组合项(用于显示 AlertDialog),或者更改现有的可组合项以处理 higher-level 可组合项上的事件,即,使可组合不耦合到导航的业务逻辑。