Использование LiveData без LifecycleObserver - PullRequest
0 голосов
/ 27 ноября 2018

Я пишу приложение, которое (пытается) придерживаться шаблона проектирования MVVM.Я хотел бы наблюдать за изменениями слоя модели из других частей этого слоя.Например,

Допустим, я выставляю список объектов из моей базы данных с использованием комнаты:

@Dao
interface MyDao {
    @Query("SELECT * FROM myTable")
    fun getAllElements(): LiveData<List<Element>>
}

Я бы хотел наблюдать за изменениями, как обычно, используя жизненный цикл.владелец, использующий LiveData.observeForever(). что-то вроде:

class BusinessLogicPartOfTheModel(private val myDao: MyDao) {
    private var allElements = listOf<Element>()

    init {
        myDao.getAllElements().observeForever { observedElements ->
            allElements = observedElements
        }
}

Однако я обнаружил, что если я зарегистрирую такого наблюдателя, как , а также более стандартного наблюдателя в ViewModel и Fragment, какthis:

class MyViewModel(private val myDao: MyDao) : ViewModel() {
    fun getAllElements(): LiveData<List<Elements>> {
        myDao.getAllElements()
    }
}

class MyFragment : Fragment() {
    private val myDao /* initialized here */
    private val myViewModel /* initialized here */
    private val logic = BusinessLogicPartOfTheModel(myDao)

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        val obs = Observer<List<Element>> {
             // do a thing
        }
        myViewModel.getAllElements.observe(viewLifeCycleOwner, obs)
    }
}

Вызывается только наблюдатель во фрагменте, но не наблюдатель в объекте бизнес-логики.Я могу успешно наблюдать за обновлениями во фрагменте и передавать события обратно в бизнес-логику, но это кажется невероятно ненужным уровнем косвенности.Я здесь пропускаю шаг или это вряд ли будет работать так, как я хочу?

1 Ответ

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

Вы, вероятно, должны использовать MediatorLiveData .

MediatorLiveData принимает другой LiveData в качестве источника событий, добавляя его к MediatorLiveData.

Вы можете использовать что-то вроде

val mediatorLiveData = MediatorLiveData<Item>().apply {
    addSource(yourLiveData) {
        // do something here
    }
}

Вы также можете посмотреть на Преобразования .

Transformations, такие методы как Transformation.map() и Transformation.switchMap(), которые простоиспользует MediatorLiveData под капотом.

...