У меня есть настройка моего приложения с использованием архитектуры MVVM. Проблема, которую я пытаюсь решить, состоит в том, чтобы инициировать вызов API на основе двух параметров запроса (в данном случае, источника и назначения), причем это происходит динамически и обновляется в реальном времени. Когда любое из этих значений обновляется, следует проверить, что оба значения не равны NULL, а затем сделать вызов API, основываясь на этих двух значениях.
Я играл с MediatorLiveData
и Transformations.switchMap()
, но не смог найти решение, которое работает хорошо. Попытка с использованием MediatorLiveData:
class MyViewModel(val repository: AppRepository) : ViewModel() {
val origin = MutableLiveData<Location>()
val destination = MutableLiveData<Location>()
val directions = MediatorLiveData<DrivingDirections>()
init {
directions.addSource(origin) { origin ->
if (origin != null && destination.value != null) {
directions.value = // problem here
// I want to make a call to something like
// repository.getDirections(origin, destination), but this comes
// back as LiveData<Directions> so *can't* set it to directions.value
// I, in effect, want to make directions = repository.getDirections(origin, destination),
// but then I lose the Mediator functionality
}
}
directions.addSource(destination) {
// as above
}
}
}
Итак, пытаясь использовать switchMap, я создал сырой OriginAndDestination
объект, а затем заметил изменения в нем.
class myViewModel(val repository: AppRepository) : ViewModel() {
val originAndDestination = MutableLiveData<OriginAndDestination>()
val directions: LiveData<Directions>
init {
directions = Transformations.switchMap(originAndDestination) { originAndDestination ->
// probably should do some checks that both origin and destination are not null,
// so this switch map could return null? How do I guard against null in a switch map?
repository.getDirections(originAndDestination.origin, originAndDestination.destination)
}
}
fun setOrigin(location: Location) {
// bit of problem code here... need to retrieve the current value of
// originAndDestination.value, then update the 'origin' property,
// then set it to the liveData value again to trigger the switchMap, above... while checking that the value isn't null in the first place...
// something like:
val tempValue = originAndDestination.value
if (tempValue != null) {
// update tempValue.origin
} else {
// create a new OriginAndDestination object?
}
// just feels really messy
}
fun setDestination(location: Location) {
// As above
}
}
Извините за все комментарии, но он подчеркивает некоторые болевые точки и разочарования. Я иду по этому пути все неправильно? Origin
и Destination
устанавливаются из полей пользовательского интерфейса.