如何将 viewModel 的范围限定为与 NavHost 无关的对话框可组合函数

How to scope a viewModel to a Dialog Composable Function which is not related to NavHost

我正在使用 Android 组合和视图模型,并且我有一个 ViewModel,它的范围是单个可组合函数,它是底部 sheet 视图,使用 BottomSheetScaffold and I inject the ViewModel inside the Composable function using viewModel 扩展但我有一个问题,viewModel 函数 returns 与之前创建的相同 viewModel 实例再次打开底部 sheet。

换句话说,如何将 ViewModel 的范围限定为与 NavHost 和 backStack 无关的 Dialog Composable 函数


@Composable
 fun ComposableExample(
) {
    val viewModel: ExampleViewModel= viewModel() // createdOnlyOnce and always returns old instance
}

根据 this issue,Compose 不提供任何机制来将 ViewModel 的范围限定为个人 @Composable - 您在 NavHost 的目的地之外创建的任何 ViewModel 的范围限定为activity/fragment 包含你的 ComposeView/你调用 setContent 的地方,因此,在你的 Compose 层次结构的整个生命周期中存在 - 这就是为什么你总是得到相同的实例。

请注意,Navigation Compose 具有针对 supporting dialog destinations and for supporting BottomSheetScaffold 的现有功能请求,这也会为这些类型的目的地带来相同的 ViewModel 和状态范围。您应该为这些问题加注星标以获取更新并表明您的兴趣(这有助于确定工作的优先级)。

此库使用调用 rememberScoped

将 ViewModel 或任何其他对象限定为可组合项的生命周期

https://github.com/sebaslogen/resaca

@Composable
fun ComposableExample(
) {
    val viewModel = rememberScoped { ExampleViewModel() } // createdOnlyOnce and always returns old instance
}

PS:它还支持一个可选键,以防您希望拥有多个具有不同数据的相同类型的 ViewModel,例如 rememberScoped(myId) { ExampleViewModel(myId) }