我目前有一个项目,其中包含MyItem
列表,并且使用Firebase / LiveData。它分为几组,每个组都有项目。
如果发生以下任何情况,我希望能够更新此列表:
要获取目录列表,我有一个类似这样的函数可返回LiveData,该LiveData将在项目更新(#1)时更新。
getList(id: String): LiveData<List<MyItem>> {
val data = MutableLiveData<List<MyItem>>()
firestore
.collection("groups")
.document(id)
.collection("items")
.addSnapshotListener { snapshot, exception ->
val items = snapshot?.toObjects(MyItem::class.java) ?: emptyList()
// filter items
data.postValue(items)
}
return data
}
在ViewModel中,我具有处理这种情况的逻辑。
private val result = MediatorLiveData<Resource<List<MyItem>>>()
private var source: LiveData<List<MyItem>>? = null
val contents: LiveData<Resource<List<MyItem>>>
get() {
val group = database.group
// if the selected group is changed.
return Transformations.switchMap(group) { id ->
// showing loading indicator
result.value = Resource.loading(null)
if (id != null) {
// only 1 source for the current group
source?.let {
result.removeSource(it)
}
source = database.getList(id).also {
result.addSource(it) {
result.value = Resource.success(it)
}
}
// how to add in source of filter changes?
} else {
result.value = Resource.init(null)
}
return@switchMap result
}
}
逻辑很复杂,很难遵循。有没有更好的方法来构造它来处理多个不同的更改?存储用户当前过滤器的最佳方法是什么?
谢谢。
答案 0 :(得分:1)
我不知道我是否正确回答了您的问题,但是如果您的视图使用一个列表(例如compile
之类的东西),并且该列表在多种情况下已更新或更改,则您必须工作与MyItemList
。
我的意思是,您必须有三个MediatorLiveData
,每个负责一个情况,一个MediatorLiveData通知每个人是否已更改。
请参见下文
LiveData
在fun getListFromServer(id: String): LiveData<List<MyItem>> {
val dataFromServer = MutableLiveData<List<MyItem>>()
firestore
.collection("groups")
.document(id)
.collection("items")
.addSnapshotListener { snapshot, exception ->
val items = snapshot?.toObjects(MyItem::class.java) ?: emptyList()
dataFromServer.postValue(items)
}
return dataFromServer
}
fun getFilteredData(id: String): LiveData<FilterData> {
return DAO.user.getFilteredData(id)
}
fun getBookmarkedList(id: String): LiveData<BookmarkData> {
return DAO.user.getBookmarkedData(id)
}
中,您有一个viewModel
会在这MediatorLiveData
上观察,直到有任何数据更改通知视图为止。
liveData
答案 1 :(得分:1)
您对contents
的实现包括对外部变量的多个引用,这使得难以跟踪和跟踪状态。我只是将引用尽可能地保留在本地,并信任switchMap(liveData)
做适当的工作。以下代码应该与您的代码相同:
val contents = Transformations.switchMap(database.group) { id ->
val data = MediatorLiveData<Resource<List<MyItem>>()
if (id == null) {
data.value = Resource.init(null)
} else {
data.value = Resource.loading(null)
data.addSource(database.getList(id)) {
data.value = Resource.success(it)
}
}
return liveData
}
关于getList(id)
,您可能还希望正确处理exception
。