Почему LiveData setValue игнорируется при вызове дважды? - PullRequest
1 голос
/ 04 апреля 2020

У меня есть следующая ViewModel с MutableLiveData data и другой LiveData ones, которая получена из data таким образом, что она обновляет свое значение, только если data.number равно 1.

class DummyViewModel : ViewModel() {

    private val data = MutableLiveData<Dummy>()
    val ones = data.mapNotNull { it.takeIf { it.number == 1 } }

    init {
        data.value = Dummy(1, "Init")
        doSomething()

    }

    fun doSomething() {
        data.value = Dummy(2, "Do something")
    }
}

data class Dummy(val number: Int, val text: String)

fun <T, Y> LiveData<T>.mapNotNull(mapper: (T) -> Y?): LiveData<Y> {
    val mediator = MediatorLiveData<Y>()
    mediator.addSource(this) { item ->
        val mapped = mapper(item)
        if (mapped != null) {
            mediator.value = mapped
        }
    }
    return mediator
}

Я наблюдаю ones в моем фрагменте. Однако, если я выполню doSomething, я не получу никаких обновлений в моем фрагменте. Если я не выполню doSomething, фиктивная Init правильно присутствует в ones, и я получу обновление.

Что здесь происходит? Почему ones пусто и как я могу решить эту проблему?

1 Ответ

2 голосов
/ 05 апреля 2020

Может быть, я что-то упускаю, но поведение кажется мне ожидаемым ...

Давайте попробуем воспроизвести оба случая последовательно.

Без doSomething ():

  1. Создать Livedata
  2. Добавить Dummy(1, "Init")
  3. Начать прослушивание во фрагменте: поскольку число равно 1, оно проходит ваш фильтр, а фрагмент получает его

С помощью doSomething ():

  1. Создать Livedata
  2. Добавить Dummy(1, "Init")
  3. Добавить Dummy(2, "Do something") (LiveData сохраняет только последнее значение, поэтому, если никто не наблюдает, первое значение теряется)
  4. Начать прослушивание во фрагменте: поскольку число равно 2, значение фильтруется, и фрагмент ничего не получает

Немного оффтопа c: всегда хорошо писать тесты для подобных случаев ViewModel, потому что вы сможете выделить проблему и быстро найти реальную причину.

РЕДАКТИРОВАТЬ: также будет Помните, что ваш фильтр работает только на наблюдениях, он не применяется при установке значения в LiveData.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...