如何解决当Activity的searchView更改存储库中的数据时,片段和viewmodel中的实时数据不会触发onChange更新
我正在使用带有MVVM +存储库+带有改造的NodeJS后端结构的应用程序。我面临的问题如下:
- 我的活动中有一个searchView(用于输入城市名称)。此searchView的onSubmit调用以city为参数的viewmodel函数,进而调用存储库函数以使用改造从后端获取数据。我已经对此进行了测试,并且可以正确提取数据并在Room数据库中对其进行更新。如果我在数据库中打印数据,则可以看到所有提取的数据。
- 现在,我想用此数据更新片段UI。早些时候,我已将Fragment与自己的Viewmodel绑定在一起,该Viewmodel返回一个“延迟延迟的LiveData”,并观察从数据库返回的数据(Livedata) 我的问题是片段UI无法获取此更新的数据。流程很简单,活动从存储库中的视图模型设置数据,而片段则观察该数据的变化。希望我能说清楚。我已经在下面附加了我的代码。
调用ViewModel的活动代码
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
runBlocking {
viewModel.setQueryToRepository(query)
}
活动的视图模型可更新存储库中的城市
suspend fun setQueryToRepository(city: String){
weatherRepository.setCity(city)
}
存储库内部的实现
private var city: String = ""
override suspend fun setCity(city: String){
this.city = city
Log.d("data","city: ${this.city}")
getSearchedWeather()
}
override suspend fun getSearchedWeather(): LiveData<out CurrentWeatherEntity> {
return withContext(Dispatchers.IO) {
if (city == ""){
return@withContext currentWeatherDAO.getCurrentWeatherFromDB(34.04563903808594,-118.24163818359375)
}
val (lat,lng) = getLocationFromAddress(city)
Log.d("data","lat: $lat,lon: $lng,city: $city")
initFetchSearchedWeatherData(lat,lng,city)
Log.d("data","return value is: ${currentWeatherDAO.getByCity(city)}")
return@withContext currentWeatherDAO.getCurrentWeatherFromDB(1.352083,103.819836)
}
}
initFetchSearchedWeatherData(lat,lng,city)函数决定是否进行提取(基于数据的新鲜度),如果是,它将调用改造并更新其Livedata,我在存储库的init函数中观察到的是这样的。 / p>
init{
weatherNetworkDataSource.downloadedCurrentWeather.observeForever{ newCurrentWeather ->
Log.d("data","changed data is,lat: ${newCurrentWeather.location.latitude},lng: ${newCurrentWeather.location.longitude}")
persistFetchedCurrentWeather(newCurrentWeather)
}
persistFetchedCurrentWeather()函数只是将数据向上插入数据库的current_weather表中。
private fun persistFetchedCurrentWeather(fetchedWeather: CurrentWeatherEntity){
Log.d("data","data in persist is,lat: ${fetchedWeather.location.latitude},lng: ${fetchedWeather.location.longitude}")
GlobalScope.launch(Dispatchers.IO) {
currentWeatherDAO.upsertCurrentWeatherData(fetchedWeather)
val data = currentWeatherDAO.getAllData()
data.map {
Log.d("data","entry is ${it.location}")
}
}
}
所以我最终从表返回Livedata为:
return@withContext currentWeatherDAO.getWeatherByCity(city)
为方便起见,我将总结存储库中的功能。
- SearchView的onSubmit活动调用存储库的setCity,后者将查询设置为城市并调用getSearchedWeather()
- getSearchedWeather()决定是否进行api调用并返回数据(来自db的Livedata)
- 我的片段通过我的片段视图模型观察此Livedata,并应更新UI。
我从其视图模型观察Livedata的片段
viewModel = ViewModelProvider(requireActivity(),viewModelFactory)
.get(WeatherSearchResultViewModel::class.java)
bindUI()
val searchedWeather = viewModel.getDataFromRepository.await()
searchedWeather.observe(viewLifecycleOwner,Observer {
if (it == null) {
group_ready.visibility = View.GONE
group_loading.visibility = View.VISIBLE
return@Observer
}
// Update UI here
})
以及Fragment的视图模型,将其作为Livedata从存储库的getSearchedWeather(上面添加的代码)中以Livedata的形式返回
val getDataFromRepository by lazyDeferred {
weatherRepository.getSearchedWeather()
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。