繁体   English   中英

在 Jetpack Compose -> Composable 函数中使用输入参数启动 ViewModel

[英]Initiating a ViewModel with Input parameters in Jetpack Compose -> Composable function

我有一个以字符串作为参数的 ViewModel

class ComplimentIdeasViewModel(ideaCategory : String) : ViewModel()  {
    //some code here
}

在不使用 ViewModel 工厂和 Hilt 的情况下,在可组合的乐趣中启动此 ViewModel 的最佳方法是什么? 一个简单的语句似乎在可组合的乐趣中实现了这一点

@Composable
fun SampleComposableFun() {
    val compIdeasViewModel = remember { ComplimentIdeasViewModel("someCategory") }
}

当我尝试这样做时,Android studio 中没有警告,但这似乎太容易了,我可以在没有依赖注入和 ViewModelFactory 类的情况下做到这一点。 我在这里错过了什么吗?

如果 viewmodel,这不会为您提供正确的实例。 看看你是否在 viewmodel 中存储了一些状态,然后使用工厂来初始化它是必要的,以确保你获得当前存在的 viewmodel 的相同和最新副本。 没有错误,因为语法实现是正确的。 我不知道有什么方法可以做到这一点,因为大多数时候,您不需要这样做。 为什么不在顶级容器中初始化它,比如活动? 然后在必要的地方传递它。

我已经尝试过你是如何写出你的,但我在屏幕旋转重置视图模型时遇到了问题。 我怀疑你也可能。

为此,我能够通过使用 viewModel() 上的工厂参数来修复它,这对我来说效果很好。 请参阅有关如何使用它的示例的类似问题的此答案: jetpack compose pass parameter to viewModel

为您的ViewModel创建一个CompositionLocal

val YourViewModel = compositionLocalOf { YourViewModel(...) }

然后初始化它(您可能会在这里使用ViewModelProvider.Factory )。 然后将其提供给您的应用程序。

CompositionLocalProvider(
  YourViewModel provides yourInitialisedViewModel,
) {
  YourApp()
}

然后在可组合中引用它。

@Composable
fun SampleComposableFun(
  compIdeasViewModel = YourViewModel.current
) {
  ... 
}

请注意,文档说ViewModel不适合CompositionLocal因为它们会使您的可组合更难测试,使您的可组合与此应用程序绑定并使其更难使用@Preview

有些人对此非常生气。 但是,如果您设法模拟ViewModel ,因此您可以测试应用程序并使用@Preview并且您的可组合物与应用程序相关联而不是通用的,那么我认为没有问题。

您可以相当简单地模拟ViewModel ,只要它的依赖项作为参数包含在内(无论如何这是一个好习惯)。

open class MockedViewModel : MyViewModel(
  app = Application(),
  someOtherDependeny = MockedDependecy(),
)

您的ViewModel依赖项越多,您需要做的模拟就越多。 但是我没有发现它令人望而却步,并且将ViewModel作为默认参数包含在ViewModel加快了开发速度。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM