kotlin - 如何根据 LiveData Map 过滤 LiveData List?
问题描述
我要异步操作。在 viewmodel 中,两者需要一起为 UI 工作。如何根据 de LiveData 地图中的键过滤 LiveData 列表?(列表中的对象 id 对应于 Map 键)
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
private val _allJourneys = MutableLiveData<List<Journey>>()
val allJourneys: LiveData<List<Journey>> get() = _allJourneys
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
private val _enrolledMap = MutableLiveData<Map<String, String>>()
val enrolledMap: LiveData<Map<String, String>> get() = _enrolledMap
fun getEnrolled() {
viewModelScope.launch {
progressRepository.getEnrolledJourneysMapOfUser().observeForever {
Timber.d("Map values: $it")
_enrolledMap.value = it
}
}
}
fun getJourneys() {
viewModelScope.launch {
journeysRepository.getAll().observeForever { it ->
_allJourneys.value = it.filter {
// enrolledMap.containsKey(it.id) ??? Nullpointer
}
}
}
}
解决方案
observeForever
在 ViewModel 中是错误的方法。每次get__
调用时,都会进行一个新的订阅,并且您将获得多个订阅,并且可能会在 ViewModel 中出现内存泄漏,直到垃圾收集器清除卡住的订阅。
相反,当您使用 LiveData 时,您应该只使用返回值并将它们保留为字段。
val allJourneys: LiveData<List<Journey>> get() = journeysRepository.getAll()
val enrolledMap: LiveData<Map<String, String>> get() = progressRepository.getEnrolledJourneysMapOfUser()
//fun getEnrolled() {
// viewModelScope.launch {
// .observeForever {
// Timber.d("Map values: $it")
// _enrolledMap.value = it
// }
// }
//
//}
//fun getJourneys() {
// viewModelScope.launch {
// .observeForever { it ->
// _allJourneys.value = it.filter {
// // enrolledMap.containsKey(it.id) ??? Nullpointer
// }
// }
// }
//}
因为来自 DAO 的存储库中的 LiveData 已经处理后台数据获取。
如果这是通过存储库中的挂起函数手动完成的,那么您可以使用switchMap
+ liveData { emitSource
- 但在这种情况下,似乎没有必要。
推荐阅读
- d3.js - 如何执行 .exit() 从以前版本的 d3.js 到版本 5.9.2 的等效操作?
- arrays - 快速查找排序下拉列表
- c# - 如何在没有自己的节点的情况下使用 QBitNinja 客户端检查比特币余额?
- laravel - 由于 [Vue 警告] 在 DELETE 路由上获得 500:避免使用非原始值作为键,而是使用字符串/数字值
- oracle - 循环经过不同时间的波谷数据块
- jquery - 点击时不调用函数
- sql - SQL中的交易、发票和文档关系
- ios - 如何创建 Swift 空二维数组以供以后添加值
- python - 我想用空格替换特殊字符
- opengl - 顶点着色器中从相机到对象的 XY 距离