我在ViewModel中有一个SharedFlow,在那里我调用repository,从数据库中通过一些id检索单个记录。每当用户点击RecyclerView中的一些记录时,都会设置这个参数。问题是我经常得到null,但如果我在repository参数中硬编码id,那么一切都很好。
DAO
@Query("SELECT * FROM employees WHERE id = :id")
fun getEmployeeById(id: Int?): Flow<EmployeeModel>
存储库接口
fun getEmployeeById(id: Int?): Flow<EmployeeModel>
存储库实现
override fun getEmployeeById(id: Int?): Flow<EmployeeModel> {
return employeeDAO.getEmployeeById(id)
}
视图模型
var employeeById: SharedFlow<DatabaseState<EmployeeModel>> = repository.get().getEmployeeById(employeeId.value?.toInt())
.map {
println("onCreateView in VM. ID ${employeeId.value} | data: $it")
DatabaseState.Success(it) }
.catch { DatabaseState.Error(it.message) }
.shareIn(viewModelScope, SharingStarted.WhileSubscribed(), replay = 0)
碎片
viewLifecycleOwner.lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
mViewModel.employeeById.collect{ employee ->
when (employee){
is DatabaseState.Success -> {
Log.i(TAG, "onCreateView APDEJCIK: ${mViewModel.employeeId.value} | ${employee.data}")
}
is DatabaseState.Error -> {
Log.i(TAG, "onCreateView: Failed to retrieve data about employee in UpdateFragmentEmployee fragment")}
}
}
}
}
正如你所看到的,我从ViewModel中记录了几次ID,它每次都有正确的ID到我点击的位置,所以ID应该没问题。
编辑:模型类
@Entity(tableName = "employees")
data class EmployeeModel(
@PrimaryKey(autoGenerate = true)
val id: Int,
@ColumnInfo(name = "name")
val name: String,
@ColumnInfo(name = "surname")
val surname: String,
@ColumnInfo(name = "age")
val age: Int,
@ColumnInfo(name = "workplace")
val workplace: String,
@ColumnInfo(name = "salary")
val salary: Double
)
1条答案
按热度按时间biswetbf1#
我认为下面这些代码有问题
因为这个声明,你的
employeeById
将在你的视图模型创建时被创建,所以employeeId.value
仍然是null。然后,因为SharingStarted.WhileSubscribed()
。map函数只会在你的流在你的repeatOnLifecycle(Lifecycle.State.STARTED)
上有一个订阅者时被调用。此时,你的employeeId.value
被设置为正确的值。这就是为什么你会得到一个非常奇怪的日志。为了解决你的问题,我认为有些事情需要改变。
您的DAO
你的viewModel。我假设你有一个员工的状态流。你应该使用
flatMap
来更新你的employeeById值,每当你的员工发生变化时。最后,如果使用
employeeById
显示数据,请考虑使用StateFlow
而不是SharedFlow