android - Android:Firebase ViewModel 架构
问题描述
我有 viewModel 类、firebase 类和一个片段。
在片段中,我从 viewModel 观察微生物列表:
viewModel = ViewModelProvider(this).get(ViewModelMicrobes::class.java)
viewModel.microbes.observe(viewLifecycleOwner, Observer { microbes ->
var microbesList = mutableListOf<Microbe>()
for(microbeMap in microbes){
val microbe = Microbe(microbeMap["name"] as String)
microbesList.add(microbe)
}
adapter.microbes = microbesList
})
viewModel.fetchMicrobes(this)
在 viewModel 类中,我从 firebase 类中获取微生物:
fun fetchMicrobes(owner: ViewModelStoreOwner){
val firebase = FirebaseMicrobes()
firebase.fetchMicrobes(owner)
}
fun setMicrobes(microbeMaps: List<Map<String, Any>>){
_microbes.value = microbeMaps
}
在 firebase 类中,我正在获取微生物并从 viewModel 调用 setMicrobes:
fun fetchMicrobes(owner: ViewModelStoreOwner){
val database = Firebase.database
val microbesRef = database.getReference("microbes")
microbesRef.addValueEventListener(object: ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
val children = snapshot.children
val viewModel = ViewModelProvider(owner).get(ViewModelMicrobes::class.java)
var microbes = mutableListOf<HashMap<String, Any>>()
for(child in children){
microbes.add(child.value as HashMap<String, Any>)
}
viewModel.setMicrobes(microbes)
}
override fun onCancelled(p0: DatabaseError) {
}
})
}
这是正确的方法吗?我需要在firebase类中创建一个viewModel实例,所以我在调用viewModel的方法时在片段中传递了“this”,这样viewModel的方法就可以将所有者传递给firebase类,所以firebase类可以创建viewModel实例.
解决方案
传递所有者不是一个好的选择,相反,您应该在 ypur firebase 类中定义一个 livedata,同时从 viewmodel 的 fetchMicrobe() 获取数据时开始观察从 Firebase 类传递的 Livedata,当收到响应时,将数据发布到 livedata,并且当您已经在 viewmodel 类中观察到这个 livedata,在这里设置你的列表。因此,无需传递您的所有者,您将能够获取数据,您的代码将被解耦,将遵循最佳实践,并将有助于测试您的代码。
推荐阅读
- android - 使用 Retrofit 和 Gson 从 Blogger Api JSON 中获取标签
- python - 将 Panda DataFrame 层叠在一起
- java - 如何在数字中插入逗号?
- linux - 更新 glibc 后:分段错误(核心转储)
- android - 我的应用程序无法发送获取位置的请求
- spring-boot - 如何在另一个具有循环依赖的单声道中使用单声道
- python - 在 Pandas DataFrame 中转置选定的 MultiIndex 级别
- external - 如何将外部库添加到 Spree 扩展?
- javascript - 从范围内的数组中获取唯一值?
- excel - Removeduplicates 无法用于大小取决于数据范围的数组