ViewModel предотвращает повторное получение данных - PullRequest
0 голосов
/ 03 мая 2020

Моя viewModel перезагружает мои данные, заставляя мое мерцание продолжать выполняться каждый раз, когда я получаю этот фрагмент, а также данные перезагружаются, что приводит к увеличению моего счета на Firebase

Как я могу предотвратить повторную загрузку снова данные каждый раз, когда мой фрагмент всплывает?

На мой взгляд

 viewModel.fetchShops(location).observe(viewLifecycleOwner, Observer {
            when(it){
                is Resource.Loading -> {
                    shimmer.visibility = View.VISIBLE
                    shimmer.startShimmer()}
                is Resource.Success -> {
                    shimmer.visibility = View.GONE
                    shimmer.stopShimmer()
                    adapter.setItems(it.data)
                }
                is Resource.Failure -> {
                    Toast.makeText(requireContext(),"Error fetching data",Toast.LENGTH_SHORT).show()
                }
            }
        })

Я называю это в моем onViewCreated(), поэтому каждый раз, когда этот фрагмент воссоздает мои Resource.Loading пожары, а также fetchShops(location), и это снова приводит к моей базе данных, я хочу, чтобы это выбиралось только один раз каждый раз, когда я возвращаюсь к этому фрагменту, любая идея?

ViewModel

   fun fetchShops(location:String) = liveData(Dispatchers.IO) {
            emit(Resource.Loading())
            try{
                emit(repo.fetchShops(location))
            }catch (e:Exception){
                emit(Resource.Failure(e))
            }
        }

1 Ответ

2 голосов
/ 04 мая 2020

Вы создаете новый экземпляр LiveData каждый раз, когда вызывается fetchShops(). Это означает, что любой ранее созданный LiveData (и предыдущее значение, которое он хранит) будет потерян.

Вместо этого вам следует преобразовать ваши LiveData , используя location в качестве входных данных для создания ваш liveData { } блок согласно liveData с Transformations .

private val locationQuery = MutableLiveData<String>

// Use distinctUntilChanged() to only requery when the location changes
val shops = locationQuery.distinctUntilChanged().switchMap { location ->
    // Note we use viewModelScope.coroutineContext to properly support cancellation
    liveData(viewModelScope.coroutineContext + Dispatchers.IO) {
        emit(Resource.Loading())
        try{
            emit(repo.fetchShops(location))
        }catch (e:Exception){
            emit(Resource.Failure(e))
        }
    }
}

fun setLocation(location: String) {
    locationQuery.value = location
}

Затем вы можете использовать его, обновив свой фрагмент:

// Set the current location
viewModel.setLocation(location)

// Observe the shops
viewModel.shops.observe(viewLifecycleOwner, Observer {
        when(it){
            is Resource.Loading -> {
                shimmer.visibility = View.VISIBLE
                shimmer.startShimmer()}
            is Resource.Success -> {
                shimmer.visibility = View.GONE
                shimmer.stopShimmer()
                adapter.setItems(it.data)
            }
            is Resource.Failure -> {
                Toast.makeText(requireContext(),"Error fetching data",Toast.LENGTH_SHORT).show()
            }
        }
    })
...