将 MutableLiveData 传递给其他 ViewModel 是否有效?
Is passing MutableLiveData to other ViewModels valid practice?
我有一个场景,其中两个片段(A 和 B)需要共享一个对象列表,可以从两个屏幕进行突变。 A 和 B 片段各有一个对应的 ViewModel(A_ViewModel 和 B_ViewModel)。它们包含一些关于如何改变共享数据的逻辑。
为了保持共享数据的完整性,我创建了 AB_Flow_ViewModel,它是 activity 范围的并且包含封装在 MutableLiveData
.
中的共享数据
我决定将 MutableLiveData
对象作为构造函数参数传递给 A 和 B 子片段。
我从未在任何地方见过这样的方法,但它似乎对我来说非常有效。
这样做有什么缺点吗?
这是我的解决方案的伪代码:
// Navigation: (A -> B)
class A() : Fragment() {
private val viewModel: A_ViewModel ...
override fun onViewCreated(
view: View,
savedInstanceState: Bundle?
) {
super.onViewCreated(view, savedInstanceState)
viewModel.sharedData.observe {
...
}
}
}
class A_ViewModel @Inject constructor(
val sharedData: MutableLiveData<List<Any>>
) : ViewModel() {
fun changeSharedData(newSharedData: List<Any>) {
sharedData.value = newSharedData
}
}
@Module
class A_Module {
@Provides
@FragmentScoped
fun provideSharedData(fragment: A) =
fragment.activityViewModels<AB_Flow_ViewModel>().value.sharedData
}
class B() : Fragment() {
private val viewModel: A_ViewModel ...
override fun onViewCreated(
view: View,
savedInstanceState: Bundle?
) {
super.onViewCreated(view, savedInstanceState)
viewModel.sharedData.observe {
...
}
}
}
@Module
class B_Module {
@Provides
@FragmentScoped
fun provideSharedData(fragment: B) =
fragment.activityViewModels<AB_Flow_ViewModel>().value.sharedData
}
class B_ViewModel @Inject constructor(
val sharedData: MutableLiveData<List<Any>>
) : ViewModel() {
fun changeSharedData(newSharedData: List<Any>) {
sharedData.value = newSharedData
}
}
class AB_Flow_ViewModel() : ViewModel() {
val sharedData = MutableLiveData<List<Any>>()
}
我强烈建议不要在两个片段之间共享 MutableLiveData,如果你遇到错误,调试起来会非常困难,因为你不知道谁在更改数据以及在哪里导致这种奇怪的状态。
我喜欢做的是将所有 MutableLiveData 保留在 ViewModel 中,并仅将 LiveData 公开给 Fragments/View 以供观察。 MutableLiveData 需要发生的每一个更改我都通过 ViewModel 中的一个函数来完成。
private val _sharedData = MutableLiveData<List<Any>>()
val sharedData: LiveData<List<Any>>
get() = _sharedData
我会将有趣的 changeSharedData 放在 AB_Flow_ViewModel 中,并将所有逻辑放在一个 ViewModel 而不是两个中。如果 FragA 和 FragB 的逻辑需要不同,我会使用两种不同的方法来更改相同的 LiveDdata
我有一个场景,其中两个片段(A 和 B)需要共享一个对象列表,可以从两个屏幕进行突变。 A 和 B 片段各有一个对应的 ViewModel(A_ViewModel 和 B_ViewModel)。它们包含一些关于如何改变共享数据的逻辑。
为了保持共享数据的完整性,我创建了 AB_Flow_ViewModel,它是 activity 范围的并且包含封装在 MutableLiveData
.
我决定将 MutableLiveData
对象作为构造函数参数传递给 A 和 B 子片段。
我从未在任何地方见过这样的方法,但它似乎对我来说非常有效。
这样做有什么缺点吗?
这是我的解决方案的伪代码:
// Navigation: (A -> B)
class A() : Fragment() {
private val viewModel: A_ViewModel ...
override fun onViewCreated(
view: View,
savedInstanceState: Bundle?
) {
super.onViewCreated(view, savedInstanceState)
viewModel.sharedData.observe {
...
}
}
}
class A_ViewModel @Inject constructor(
val sharedData: MutableLiveData<List<Any>>
) : ViewModel() {
fun changeSharedData(newSharedData: List<Any>) {
sharedData.value = newSharedData
}
}
@Module
class A_Module {
@Provides
@FragmentScoped
fun provideSharedData(fragment: A) =
fragment.activityViewModels<AB_Flow_ViewModel>().value.sharedData
}
class B() : Fragment() {
private val viewModel: A_ViewModel ...
override fun onViewCreated(
view: View,
savedInstanceState: Bundle?
) {
super.onViewCreated(view, savedInstanceState)
viewModel.sharedData.observe {
...
}
}
}
@Module
class B_Module {
@Provides
@FragmentScoped
fun provideSharedData(fragment: B) =
fragment.activityViewModels<AB_Flow_ViewModel>().value.sharedData
}
class B_ViewModel @Inject constructor(
val sharedData: MutableLiveData<List<Any>>
) : ViewModel() {
fun changeSharedData(newSharedData: List<Any>) {
sharedData.value = newSharedData
}
}
class AB_Flow_ViewModel() : ViewModel() {
val sharedData = MutableLiveData<List<Any>>()
}
我强烈建议不要在两个片段之间共享 MutableLiveData,如果你遇到错误,调试起来会非常困难,因为你不知道谁在更改数据以及在哪里导致这种奇怪的状态。 我喜欢做的是将所有 MutableLiveData 保留在 ViewModel 中,并仅将 LiveData 公开给 Fragments/View 以供观察。 MutableLiveData 需要发生的每一个更改我都通过 ViewModel 中的一个函数来完成。
private val _sharedData = MutableLiveData<List<Any>>()
val sharedData: LiveData<List<Any>>
get() = _sharedData
我会将有趣的 changeSharedData 放在 AB_Flow_ViewModel 中,并将所有逻辑放在一个 ViewModel 而不是两个中。如果 FragA 和 FragB 的逻辑需要不同,我会使用两种不同的方法来更改相同的 LiveDdata