android - 在 Jetpack Compose -> Composable 函数中使用输入参数启动 ViewModel
问题描述
我有一个将字符串作为参数的 ViewModel
class ComplimentIdeasViewModel(ideaCategory : String) : ViewModel() {
//some code here
}
在不使用 ViewModel 工厂和 Hilt 的情况下,在可组合的乐趣中启动此 ViewModel 的最佳方式是什么?一个简单的语句似乎在可组合的乐趣中实现了这一点
@Composable
fun SampleComposableFun() {
val compIdeasViewModel = remember { ComplimentIdeasViewModel("someCategory") }
}
当我尝试这样做时,Android Studio 中没有任何警告,但这似乎太容易实现了,我可以在没有依赖注入和 ViewModelFactory 类的情况下做到这一点。我在这里错过了什么吗?
解决方案
为CompositionLocal
您的ViewModel
.
val YourViewModel = compositionLocalOf { YourViewModel(...) }
然后初始化它(你可能会在ViewModelProvider.Factory
这里使用)。然后将其提供给您的应用程序。
CompositionLocalProvider(
YourViewModel provides yourInitialisedViewModel,
) {
YourApp()
}
然后在可组合中引用它。
@Composable
fun SampleComposableFun(
compIdeasViewModel = YourViewModel.current
) {
...
}
请注意,文档说ViewModel
s 不适合CompositionLocal
s,因为它们会使您的可组合项更难测试,使您的可组合项与此应用程序绑定并使其更难使用@Preview
。
有些人对此非常生气。但是,如果您设法模拟出ViewModel
,那么您可以测试应用程序并使用@Preview
,并且您的可组合项与应用程序相关联而不是通用的,那么我认为没有问题。
您可以相当简单地模拟一个ViewModel
,只要它的依赖项作为参数包含在内(无论如何这是一个好习惯)。
open class MockedViewModel : MyViewModel(
app = Application(),
someOtherDependeny = MockedDependecy(),
)
您的依赖ViewModel
项越多,您需要做的模拟就越多。但我并没有发现它令人望而却步,并且将其ViewModel
作为默认参数极大地加快了开发速度。
推荐阅读
- css - Chrome 中表格边框样式的问题(适用于 FF)
- coldfusion - Lucee - 如何设置虚拟站点和访问网络管理员?
- triggers - 为两个不同对象设置相同值的测试类
- c# - 球员触地时死亡
- r - 无法用 dplyr() 计算 mean()
- javascript - Firefox 扩展:事件侦听器未添加到某些元素
- java - 使用 Java,这个 charAt(); 怎么样?把一个字符串变成一个int?
- python - Python 事件循环不能与标准输入一起正常工作
- bixby - 如何在 Bixby 故事测试中查看断言的控制台输出?
- javascript - 如何在对象集合中找到特定值?