ViewModel防止重新获取数据

时间:2020-05-03 20:18:01

标签: android firebase android-fragments kotlin

我的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)射击和 fun fetchShops(location:String) = liveData(Dispatchers.IO) { emit(Resource.Loading()) try{ emit(repo.fetchShops(location)) }catch (e:Exception){ emit(Resource.Failure(e)) } } 都将再次提取到我的数据库中,我希望它只提取一次每次我回到这个片段时,有什么想法吗?

ViewModel

    <form (ngSubmit)="searchTrain()">
        <div class="input-group">
            <select name="source" [(ngModel)]="source" required>
                <option [value]="" [selected]="true">-- source --</option>
                <option *ngFor="let src of sourceList" [value]="src">{{src}}</option>
            </select>
        <div class="text-center">
            <button type="submit" class="btn btn-primary">Find Trains</button>
        </div>
    </form>

1 个答案:

答案 0 :(得分:2)

每次调用LiveData时,您正在创建一个新的fetchShops()实例。这意味着所有先前创建的LiveData(及其存储的先前值)都会丢失。

相反,您应该Tranform your LiveData,以location作为输入,按照liveData with Transformations 创建liveData { }块。

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()
            }
        }
    })