将 activity 的 ViewModel 注入片段的 ViewModel
Inject activity's ViewModel into fragment's ViewModel
我设置了一个与 GithubBrowserSample
非常相似的项目。所以,匕首的设置是一样的。
考虑有 ActivityViewModel
和 FragmentViewModel
,它们具有 non-zero arg 构造函数,因此它们是通过自定义 ViewModelProvider.Factory
从 ViewModelProviders
获取的。
我想要的是指示 dagger 在以下代码中注入已经创建的 ActivityViewModel
实例:
class FragmentViewModel @Inject constructor(
private val activityViewModel: ActivityViewModel
private val foo: Foo
) : ViewModel() {
...
}
使用当前声明,Dagger 将创建 ActivityViewModel
的 new 实例,无论是否已经存在。
发生这种情况,因为 ActivityViewModel
.
存在一个 @Inject
带注释的构造函数
因此,dagger 可以自由假设,这是将 ActivityViewModel
实例提供给 FragmentViewModel
的正确方法。
我知道如何为普通的 Dagger 制作东西,但我不知道如何为 Dagger-Android 制作东西,这个问题专门针对 Dagger-Android 设置。
作为一个肮脏的解决方案,我目前正在手动设置该实例:
class MyFragment : Fragment {
...
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProviders.of(this, viewModelFactory).get(FragmentViewModel::class.java)
viewModel.activityViewModel = ViewModelProviders.of(activity!!, viewModelFactory).get(ActivityViewModel::class.java)
}
...
}
将 parent 的 ViewModel
注入 child 的 ViewModel
的正确方法是什么?
这不是问题的答案,而是我提出并目前正在使用的一种方法。
已声明以下扩展函数:
inline fun <reified T : ViewModel> Fragment.getViewModel(
factory: ViewModelProvider.Factory = ViewModelProvider.NewInstanceFactory()
) = ViewModelProviders.of(this, factory).get(T::class.java)
inline fun <reified T : ViewModel> Fragment.getParentViewModel(
factory: ViewModelProvider.Factory = ViewModelProvider.NewInstanceFactory()
) = ViewModelProviders.of(activity!!, factory).get(T::class.java)
然后在片段class中我们可以声明如下:
private val parentViewModel by lazy { getParentViewModel<ParentViewModel>(viewModelFactory) }
private val childViewModel by lazy {
val field = getViewModel<ChildViewModel>(viewModelFactory)
field.parentViewModel = parentViewModel
field
}
我设置了一个与 GithubBrowserSample
非常相似的项目。所以,匕首的设置是一样的。
考虑有 ActivityViewModel
和 FragmentViewModel
,它们具有 non-zero arg 构造函数,因此它们是通过自定义 ViewModelProvider.Factory
从 ViewModelProviders
获取的。
我想要的是指示 dagger 在以下代码中注入已经创建的 ActivityViewModel
实例:
class FragmentViewModel @Inject constructor(
private val activityViewModel: ActivityViewModel
private val foo: Foo
) : ViewModel() {
...
}
使用当前声明,Dagger 将创建 ActivityViewModel
的 new 实例,无论是否已经存在。
发生这种情况,因为 ActivityViewModel
.
@Inject
带注释的构造函数
因此,dagger 可以自由假设,这是将 ActivityViewModel
实例提供给 FragmentViewModel
的正确方法。
我知道如何为普通的 Dagger 制作东西,但我不知道如何为 Dagger-Android 制作东西,这个问题专门针对 Dagger-Android 设置。
作为一个肮脏的解决方案,我目前正在手动设置该实例:
class MyFragment : Fragment {
...
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProviders.of(this, viewModelFactory).get(FragmentViewModel::class.java)
viewModel.activityViewModel = ViewModelProviders.of(activity!!, viewModelFactory).get(ActivityViewModel::class.java)
}
...
}
将 parent 的 ViewModel
注入 child 的 ViewModel
的正确方法是什么?
这不是问题的答案,而是我提出并目前正在使用的一种方法。
已声明以下扩展函数:
inline fun <reified T : ViewModel> Fragment.getViewModel(
factory: ViewModelProvider.Factory = ViewModelProvider.NewInstanceFactory()
) = ViewModelProviders.of(this, factory).get(T::class.java)
inline fun <reified T : ViewModel> Fragment.getParentViewModel(
factory: ViewModelProvider.Factory = ViewModelProvider.NewInstanceFactory()
) = ViewModelProviders.of(activity!!, factory).get(T::class.java)
然后在片段class中我们可以声明如下:
private val parentViewModel by lazy { getParentViewModel<ParentViewModel>(viewModelFactory) }
private val childViewModel by lazy {
val field = getViewModel<ChildViewModel>(viewModelFactory)
field.parentViewModel = parentViewModel
field
}