【问题标题】:How to call a ViewModel method from another one in android kotlin?如何从android kotlin中的另一个调用ViewModel方法?
【发布时间】:2021-06-07 12:12:17
【问题描述】:

我有一个扩展 AndroidViewModel 类的 UserViewModel,这个类有一个 User 类型的 MutableLiveData,里面有像用户信用这样的信息,这个视图模型还有一个 editCredit 方法,它设置用户拥有的新信用量(节省DB 和 postValue 用户属性,以便可以在视图中观察)

我拥有的另一个 AndroidViewModel 类是 CourseViewModel,它具有 courseList 或 currentCourse 等属性。它还有一个名为 buyCourse 的方法,该方法需要减少用户信用并将该课程添加到用户课程列表中。第二个属性位于 CourseViewModel 类中,我可以轻松更新该列表,但为了减少用户的信用,我需要调用位于其他 viewModel 类中的 editCredit 方法。

我知道我可以在视图层中使用一些逻辑并在那里调用 courseViewModel.buyCourse 然后添加一个可观察的方法,这样当它添加到用户的课程列表时,我可以收到通知并在该层调用 userViewModel.editCredit,但我的问题是:

Is there any way, a viewModel class can call another ViewModel class's methods?

更新---

在我开始耦合我的视图模型之前,我有一个包含 400 多行代码的视图模型,但它可以轻松完成这项工作,但很难阅读(那里没有太多逻辑,只调用存储库函数) 所以我尝试将它们更改为更小的视图模型类,但现在我被卡住了。

【问题讨论】:

  • Is there any way, a viewModel class can call another ViewModel class's methods? 似乎不是一个好主意。如果一个组件需要数据才能工作,那么该数据就是一种依赖关系,并且有已知的处理依赖关系的方法。在你的虚拟机中需要另一个虚拟机只是一种隐藏你实际需要数据这一事实的方式,这些数据可以被传递
  • 在开始将您的 ViewModel 相互耦合之前,我建议您阅读 ViewModel 以及它在应用程序中的实际用途。
  • @OhhhThatVarun 感谢您的 cmets,实际上我一开始只有一个类,但它开始增长并增长并变成了 400 多行代码(主要是在 ViewModelScope 中调用存储库挂起函数)所以随着它的排列变得越来越难以阅读和调试,这就是为什么我试图将它分成更小的类,但处理这些依赖项似乎并不容易,有什么建议吗?
  • @a_local_nobody 也感谢您的评论,实际上我正在寻找一种在 viewModel 之间进行协商以保持它们独立的方式,而一个巨大的 viewModel 可以拆分成更小的那些,但似乎没有一个标准这样做的方法

标签: android kotlin android-viewmodel android-mvvm


【解决方案1】:

正如已经提到的,您不应该这样做。 ViewModel 不应该相互了解,但如果你真的需要这样做:

您可以做的是以接口的形式提供所需的方法。该接口将由一个 ViewModel 扩展,并在初始化时使用WeakReference 提供给第二个 ViewModel(稍微了解一下),以确保不会发生内存泄漏。

interface EditCredit {
  fun editCredit()
}
class UserViewModel : EditCredit {
   override fun editCredit() {
      // do sth
   }
}
class CourseViewModel {
  var editCredit: EditCredit? by weak() // by using weak() I just want to indicate you should handle it properly

   fun someFunctionThatNeedsEditCredit() {
      editCredit?.editCredit()
   }
}
class SomeActivity {
     val userViewModel: UserViewModel
     val courseViewModel: CourseViewModel

     override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        userViewModel = //initialize it
        courseViewModel = //initialize it
        courseViewModel.editCredit = userViewModel
     }

}

【讨论】:

  • 感谢这是一个很好的解决方案,正如您所说,这可能不是最佳实践,但由于它使我的程序更易于阅读和调试,我相信它值得使用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-01
  • 2015-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-13
相关资源
最近更新 更多