在 MVVM 中处理 ViewModel 和 Fragment 中的数据
Handle data in ViewModel and Fragment in MVVM
我看过很多教程,但并没有真正让自己正确理解如何处理 MVVM 中的某些情况。
假设有一个存储库从使用 Room
的 DAO
获取数据
class Repository(){
fun getItems() = itemsDAO.getItems()
}
查询存储库的 ViewModel
class FragmentViewModel:ViewModel(){
val items = repository.getItems()
fun updateItem(Item item){
repository.updateImte(itemm)
}
}
还有一个片段
class MyFragment:Fragment(){
//onViewCreated
viewModel.items.observe(...){
//if result, update the views
}
buttonUpdateItem.setOnClickListener{
viewModel.updateItem(Item item)
}
}
这是我从教程中了解到的方法。基本上我有一些事情要澄清,我想请求你的帮助。
一个。鉴于 ViewModel
的这种实现,如果用户旋转设备并重新创建片段,这是否意味着在添加 observe
时将再次查询数据库?
我正在考虑像
这样的 ViewModel 的更新版本
class FragmentViewModel:ViewModel(){
private final var itemsObservable;
init {
itemsObservable = repository.getItems()
}
fun items(){
return itemsObservable
}
fun updateItem(Item item){
repository.updateImte(item)
}
}
如果我是对的,这应该允许 return 来自 db 的初始值,并且在片段重建的情况下不会再次调用 db。
b。 ViewModel
应该如何作用于 Fragment
交互,更精确地作用于按钮点击事件? fragment
是否应该像上面的示例那样调用 viewModel.updateItem
函数,或者 viewModel
应该 return 应该设置为按钮的 onClickListener
变量?
c。传递给 fragment
的参数是否也应该添加到 ViewModel
?
d。如您所见,ViewModel
保存 LiveData<List<>>
的变量,例如,如果我想更新一个项目,那么 fragment
传递 Item
。这是一个好方法吗?
首先我想向您指出
Android Architecture Blueprints 在 GitHub 上:
The focus of this project is on demonstrating how to structure your
code, design your architecture, and the eventual impact of adopting
these patterns on testing and maintaining your app. You can use the
techniques demonstrated here in many different ways to build apps.
Your own particular priorities will impact how you implement the
concepts in these projects, so you should not consider these samples
to be canonical examples.
这些是 Android 中不同架构的官方示例,您绝对应该检查一下,作为您自己项目的灵感。
一个。您的更新版本是执行此操作的正确方法 - 要检索项目列表,调用存储库方法一次并将 return 值存储在 ViewModel
中。在您的 DAO 中使用 LiveData<List<Item>>
作为 return 值,Room 将自动通知您在 Fragment
中的 Observer
任何更改。
b。 ViewModel
可以有 updateItem(item: Item)
方法。 onClickListener
应放在 Fragment
中。在调用 updateItem
方法之前,您可能还想在 Fragment
中进行一些验证。同样重要的是不要在 ViewModel
.
中保留任何 View
引用
要通知 Fragment
关于更新状态,您可以考虑在 ViewModel
中有另一个 LiveData
字段(例如 errorMessage: LiveData<Int>
)并将其分配给 R. id
您要显示的字符串资源。通过这种方式,您可以将确定要显示的特定消息的逻辑从 Fragment
移动到 ViewModel
。
c。您只需要 ViewModel
中的一些参数。例如,当您在 Bundle
中将一个 id 额外参数传递给 Fragment
时,您将使用此 id 初始化 ViewModel
以加载项目。
d。通过 Item
绝对是一个好方法。您还可以考虑创建一个 Presenter 来将一些逻辑从 Fragment
中分离出来(因此它不适用于 Item
)。您将在上面的 GitHub link 中找到更多信息和示例。
所以我认为根据您正在开发的应用程序,可以选择不同的方法。测试非常重要,在实施一种方法后,您会发现它如何影响编写测试的难易程度。但这就是我看到你的问题的答案。
我看过很多教程,但并没有真正让自己正确理解如何处理 MVVM 中的某些情况。
假设有一个存储库从使用 Room
DAO
获取数据
class Repository(){
fun getItems() = itemsDAO.getItems()
}
查询存储库的 ViewModel
class FragmentViewModel:ViewModel(){
val items = repository.getItems()
fun updateItem(Item item){
repository.updateImte(itemm)
}
}
还有一个片段
class MyFragment:Fragment(){
//onViewCreated
viewModel.items.observe(...){
//if result, update the views
}
buttonUpdateItem.setOnClickListener{
viewModel.updateItem(Item item)
}
}
这是我从教程中了解到的方法。基本上我有一些事情要澄清,我想请求你的帮助。
一个。鉴于 ViewModel
的这种实现,如果用户旋转设备并重新创建片段,这是否意味着在添加 observe
时将再次查询数据库?
我正在考虑像
class FragmentViewModel:ViewModel(){
private final var itemsObservable;
init {
itemsObservable = repository.getItems()
}
fun items(){
return itemsObservable
}
fun updateItem(Item item){
repository.updateImte(item)
}
}
如果我是对的,这应该允许 return 来自 db 的初始值,并且在片段重建的情况下不会再次调用 db。
b。 ViewModel
应该如何作用于 Fragment
交互,更精确地作用于按钮点击事件? fragment
是否应该像上面的示例那样调用 viewModel.updateItem
函数,或者 viewModel
应该 return 应该设置为按钮的 onClickListener
变量?
c。传递给 fragment
的参数是否也应该添加到 ViewModel
?
d。如您所见,ViewModel
保存 LiveData<List<>>
的变量,例如,如果我想更新一个项目,那么 fragment
传递 Item
。这是一个好方法吗?
首先我想向您指出 Android Architecture Blueprints 在 GitHub 上:
The focus of this project is on demonstrating how to structure your code, design your architecture, and the eventual impact of adopting these patterns on testing and maintaining your app. You can use the techniques demonstrated here in many different ways to build apps. Your own particular priorities will impact how you implement the concepts in these projects, so you should not consider these samples to be canonical examples.
这些是 Android 中不同架构的官方示例,您绝对应该检查一下,作为您自己项目的灵感。
一个。您的更新版本是执行此操作的正确方法 - 要检索项目列表,调用存储库方法一次并将 return 值存储在 ViewModel
中。在您的 DAO 中使用 LiveData<List<Item>>
作为 return 值,Room 将自动通知您在 Fragment
中的 Observer
任何更改。
b。 ViewModel
可以有 updateItem(item: Item)
方法。 onClickListener
应放在 Fragment
中。在调用 updateItem
方法之前,您可能还想在 Fragment
中进行一些验证。同样重要的是不要在 ViewModel
.
中保留任何 View
引用
要通知 Fragment
关于更新状态,您可以考虑在 ViewModel
中有另一个 LiveData
字段(例如 errorMessage: LiveData<Int>
)并将其分配给 R. id
您要显示的字符串资源。通过这种方式,您可以将确定要显示的特定消息的逻辑从 Fragment
移动到 ViewModel
。
c。您只需要 ViewModel
中的一些参数。例如,当您在 Bundle
中将一个 id 额外参数传递给 Fragment
时,您将使用此 id 初始化 ViewModel
以加载项目。
d。通过 Item
绝对是一个好方法。您还可以考虑创建一个 Presenter 来将一些逻辑从 Fragment
中分离出来(因此它不适用于 Item
)。您将在上面的 GitHub link 中找到更多信息和示例。
所以我认为根据您正在开发的应用程序,可以选择不同的方法。测试非常重要,在实施一种方法后,您会发现它如何影响编写测试的难易程度。但这就是我看到你的问题的答案。