[英]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
使用Livedata
或MutableLivedata
而没有动态源,例如:
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)
}
I'm in a personal project 我在一个个人项目中
Use MVVM + Live data + Repository pattern 使用MVVM +实时数据+存储库模式
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
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.