我声明了一个抽象 viewModel(比如说
AnimalsViewModel
),两个 viewModel 扩展了它(DogViewModel
,CatViewModel
)
相应的片段(
DogFragment
,CatFragment
)托管一个公共片段(AnimalFragment
),它需要父片段正在使用的任何AnimalViewModel
的实例。
但我怎样才能把它放进AnimalFragment
呢?我试过这个:
class AnimalFragment : Fragment() {
private val viewModel by lazy {
requireParentFragment().getViewModel<AnimalViewModel>()
}
}
但它不起作用,因为 koin 找不到父级拥有的实例,并抛出一个错误,指出它找不到
AnimalViewModel
的提供者(显然,因为它是抽象的)。我试图让它成为一个界面,但没有成功。
有什么办法可以实现这个目标吗?
编辑: 澄清一下,假设
DogFragment
有一个 id 为 1 的 DogViewModel
实例,并且 CatFragment
有 id 为 2 的 CatViewModel
,AnimalFragment
内部的 DogFragment
应该接收 viewModel #1 和 CatFragment
内部的 viewModel #1应该收到#2。
问题不是在正确的范围内获取 viewModel,而是使用抽象类作为标识符获取 viewModel。
这工作完美,但我不想向
AnimalFragment
添加参数来知道它应该请求哪个 viewModel
private val viewModel by lazy {
requireParentFragment().getViewModel<DogViewModel>()
}
我最终定义了一个接口,它提供了所需抽象类型的视图模型。这并不理想,但比传递参数或在子级中提及父级片段要好。
interface AnimalContainer {
abstract val viewModel: AnimalViewModel
}
class AnimalFragment : Fragment() {
private val viewModel by lazy {
(requireParentFragment() as? AnimalContainer)?.viewModel
?: error("AnimalFragment not allowed in container ${requireParentFragment()}")
}
}