LiveData, MVVM и шаблон репозитория - PullRequest
0 голосов
/ 26 сентября 2018

Это хороший подход, или я только что нашел неприятный обходной путь?

Я использую класс MediatorLiveData, потому что кажется полезным для обновленияисточник LiveData объекта.

Я имею в виду, что большинство учебных пособий, которые я нашел в Интернете, используют Livedata или MutableLivedata без динамического источника, например:

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

Но в моем случае у меня есть следующий веб-сервис, который выполняет поиск по имени:

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;
    }
}

Затем в классе 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);
            }
        });
    }
}

Деятельность

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

Сфера проекта

Я в личном проекте

Цели

Использование MVVM + Живые данные + Шаблон репозитория

Проблема

Я нашел учебники только с простым подходом: наблюдать за объектом LiveData, который обращается к объекту repository, и получать данные только один раз.

Например: выборка всех людей (select * from people) из веб-службы.

Мой случай: выборка людей, набравших имя (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

Сомнения

Является ли хорошей идеей использование MediatorLiveData класса для merge всех запросов, полученных от ввода пользователя?

Должен лиЯ использую MutableLiveData и изменяю класс repository и использую пользовательское clousure?

Есть ли лучший подход?

1 Ответ

0 голосов
/ 15 ноября 2018

Я использовал этот шаблон и с MediatorLiveData, но он создает проблему.С точки зрения пользователя, это, кажется, работает нормально, но одна проблема здесь в том, что каждый раз, когда вы вызываете performSearch(), хранилище создает новый объект LiveData, который дополнительно добавляется в MediatorLiveData через addSource().

Идеявозможно, хранилище создаст объект MutableLiveData только один раз, а при последовательном вызове просто обновите его значение.Таким образом, fe MutableLiveData<List<Person>> apiResponse; будет неинициализированным приватным полем, которое инициализируется в методе search().

Например.if (apiResponse == null) apiResponse = new MutableLiveData();

...