简体   繁体   English

LiveData,MVVM和存储库模式

[英]LiveData, MVVM and Repository Pattern

Is this a good approach or I've just found a nasty workaround? 这是一个好方法还是我刚刚找到了一个讨厌的解决方法?

I'm using MediatorLiveData class because seems useful to update the source of a LiveData object. 我正在使用MediatorLiveData类,因为似乎对更新LiveData对象的源很有用。

I mean, the majority of tutorials that I've found on internet just use Livedata or MutableLivedata without a dynamic source, in example: 我的意思是,我在互联网上找到的大多数教程Livedata使用LivedataMutableLivedata而没有动态源,例如:

fun search(/*no input params*/): Call<List<Person>>

But in my case, I have the following web service that performs a search by name: 但就我而言,我拥有以下按名称执行搜索的Web服务:

interface APIServidor {
    @GET("search")
    fun search(@Query("name") name: String): Call<List<Person>>

}

public class PeopleRepository {


    public LiveData<List<Person>> search(String name){

        final MutableLiveData<List<Person>> apiResponse = new MutableLiveData<>();
        Call<List<Person>> call = RetrofitService.Companion.getInstance().getApiServer().search(name);
        call.enqueue(new Callback<List<Person>>() {
            @Override
            public void onResponse(@NonNull Call<List<Person>> call, @NonNull Response<List<Person>> response) {
                if (response.isSuccessful()) {
                    apiResponse.postValue(response.body());
                }
            }

            @Override
            public void onFailure(@NonNull Call<List<Person>> call, @NonNull Throwable t) {
                apiResponse.postValue(null);
            }
        });

        return apiResponse;
    }
}

Then in the viewmodel class I'm adding source per new request. 然后在viewmodel类中,我为每个新请求添加源。

public class SearchViewModel extends ViewModel {

    private MediatorLiveData<List<Person>> mApiResponse;
    private PeopleRepository mApiRepo;

    public SearchViewModel() {
        mApiResponse = new MediatorLiveData<>();
        mApiRepo = new PeopleRepository();
    }

    public LiveData<List<Person>> getPlayers() {
        return mApiResponse;
    }

    public void performSearch(String name){
        mApiResponse.addSource(mApiRepo.search(name), new Observer<List<Person>>() {
            @Override
            public void onChanged(List<Person> apiResponse)            {
                mApiResponse.setValue(apiResponse);
            }
        });
    }
}

Activity 活动

bt_search.setOnClickListener {
    val player_name = et_player.text.toString()
    viewModel.performSearch(player_name)
}

Project scope 项目范围

I'm in a personal project 我在一个个人项目中

Goals 目标

Use MVVM + Live data + Repository pattern 使用MVVM +实时数据+存储库模式

Problem 问题

I've only found tutorials with a simple approach: observe a LiveData object that access to a repository object and fetch data only once. 我只发现了一种使用简单方法的教程:观察一个访问repository对象的LiveData对象,并且只获取一次数据。

In example: Fetch all people ( select * from people ) from web service. 在示例中:从Web服务获取所有人( select * from people )。

My case: Fetch people that mach a name ( select * from people where name=? ) from web service. 我的情况是:从Web服务中获取具有名称的人( select * from people where name=? )。

https://medium.com/@elye.project/kotlin-and-retrofit-2-tutorial-with-working-codes-333a4422a890 https://medium.com/@sriramr083/error-handling-in-retrofit2-in-mvvm-repository-pattern-a9c13c8f3995 https://medium.com/@elye.project/kotlin-and-retrofit-2-tutorial-with-working-codes-333a4422a890 https://medium.com/@sriramr083/error-handling-in-retrofit2-in -mvvm-库图案a9c13c8f3995

Doubts 疑惑

Is a good idea use MediatorLiveData class to merge all requests took from user input? 一个好主意是使用MediatorLiveData类来merge所有来自用户输入的请求吗?

Should I use MutableLiveData and change the repository class and use a custom clousure? 我应该使用MutableLiveData并更改repository类并使用自定义的clousure吗?

Is there a better approach? 有没有更好的方法?

I was using this pattern with MediatorLiveData as well, but it forms an issue. 我也将这种模式与MediatorLiveData一起使用,但这构成了一个问题。 From the user perspective it seems to function just fine, but one problem here is that every time you call performSearch() the repository creates a new LiveData object which is additionally added to MediatorLiveData via addSource() . 从用户角度看,它似乎还可以正常工作,但是这里的一个问题是,每次调用performSearch() ,存储库都会创建一个新的LiveData对象,该对象还通过addSource()添加到MediatorLiveData中。

An idea might be to have the repository create the MutableLiveData object only once and on consecutive call just update it's value. 一个想法可能是让存储库仅创建一次MutableLiveData对象,并且在连续调用时只需更新其值即可。 So fe MutableLiveData<List<Person>> apiResponse; 因此, MutableLiveData<List<Person>> apiResponse; would be a non initialized private field that gets initialized in the search() method. 将是在search()方法中初始化的未初始化的私有字段。

Eg. 例如。 if (apiResponse == null) apiResponse = new MutableLiveData();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 livedata、改造、mvvm 和存储库模式制作通用网络适配器 - Making a generic network adapter using livedata, retrofit, mvvm and repository pattern LiveData 和 MVVM 模式 - LiveData and MVVM pattern 使用 reteofit kotlin 的 MVVM 模式中的 LiveData - LiveData in MVVM pattern with reteofit kotlin 存储库模式未正确返回 LiveData - Repository pattern is not correctly returning LiveData Android - 带有 LiveData 组件的 MVVM 和 Repository 中的 Retrofit 调用 - Android - MVVM with LiveData component and a Retrofit call in Repository MVVM 与 Retrofit - 如何处理存储库中的大量 LiveData? - MVVM with Retrofit - How to deal with a lot of LiveData in Repository? Android MVVM 2 个 ViewModel 与 LiveData 共享 1 个存储库 - Android MVVM 2 ViewModels Sharing 1 Repository with LiveData Android MVVM/Repository 如何强制 LiveData 从存储库更新? - Android MVVM/Repository how to force LiveData to update from repository? 使用存储库模式和 LiveData 对 ViewModel 进行单元测试 - Unit test ViewModel using repository pattern and LiveData 如何在单独的存储库 (MVVM) 中传递 Firestore SnapshotListener 提供的实时数据 - How to pass through livedata provided by Firestore SnapshotListener in a separate repository (MVVM)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM