我在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实例,最接近的是活动……
根据我的理解,我需要做一些事情,比如
class FragmentB : Fragment(), KodeinAware {
override val kodeinContext = kcontext<Fragment>(this)
override val kodein: Kodein = Kodein.lazy {
extend(fragmentAKodein)
}
private val myViewModel: MyViewModel by instance()
}但我不知道怎么弄到fragmentAKodein。
非常感谢
编辑:
这就是我最终要做的:
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不认为映射器在相同的作用域中,并为每个片段实例化一个新的映射器……
发布于 2020-04-14 17:22:57
使用自定义作用域解决了我的问题:https://github.com/Kodein-Framework/Kodein-DI/issues/258
https://stackoverflow.com/questions/61172499
复制相似问题