我正在开发 Android,但我想这个概念在每个平台上都是一样的。
我有一个片段 A 使用 NavHostFragment 托管另一个片段 B。
我可以轻松地从片段 A 中检索 ViewModel:
class FragmentA : Fragment(), KodeinAware {
protected val parentKodein by closestKodein()
override val kodeinContext = kcontext<Fragment>(this)
override val kodein: Kodein = Kodein.lazy {
extend(parentKodein)
import(myViewModelModule)
}
private val myViewModel: MyViewModel by instance()
}
该模块也很简单:
val myViewModelModule = Kodein.Module(TAG) {
bind<MyViewModel>() with scoped<Fragment>(AndroidLifecycleScope).singleton {
ViewModelProvider(
this.context,
MyViewModelFactory(instance())
).get(
MyViewModel::class.java
)
}
bind<AMapper>() with scoped<Fragment>(AndroidLifecycleScope).singleton {
AMapper()
}
}
但我不知道如何在片段 B 中获得相同的 MyViewModel 实例,最接近的 kodein 是活动......
据我了解,我需要做类似的事情
class FragmentB : Fragment(), KodeinAware {
override val kodeinContext = kcontext<Fragment>(this)
override val kodein: Kodein = Kodein.lazy {
extend(fragmentAKodein)
}
private val myViewModel: MyViewModel by instance()
}
但我不知道如何获得片段AKodein。
非常感谢
编辑 :
这就是我最终做的事情:
class FragmentA : Fragment(), KodeinAware {
protected val parentKodein by closestKodein()
override val kodeinContext: KodeinContext<Fragment> by lazy { kcontext(childFragmentManager.findFragmentById(R.id.nav_host_containing_fragment_B) as Fragment)
}
override val kodein: Kodein = Kodein.lazy {
extend(parentKodein)
import(myViewModelModule)
}
private val myViewModel: MyViewModel by instance()
}
val myViewModelModule = Kodein.Module(TAG) {
bind<MyViewModel>() with scoped<BaseFragment>(AndroidLifecycleScope).singleton {
ViewModelProvider(
context.kodeinContext.value,
MyViewModelFactory(
instance()
)
).get(
MyViewModel::class.java
)
}
bind<AMapper>() with scoped<Fragment>(AndroidLifecycleScope).singleton {
AMapper()
}
}
class FragmentB : Fragment(), KodeinAware {
override val kodeinContext: KodeinContext<Fragment> by lazy {
kcontext(parentFragment as Fragment)
}
override val kodein: Kodein = Kodein.lazy {
extend(fragmentAKodein)
}
private val myViewModel: MyViewModel by instance()
}
感谢 ViewModelFactory,MyViewModel 的同一个实例在所有片段之间共享。
但这是一种解决方法,因为 Kodein 不认为映射器在同一范围内并为每个片段实例化一个新的...