I'm writing an app which is (attempting) to adhere to the MVVM design pattern. I'd like to observe changes to the model layer from other parts of that layer. For example
Let's say I'm exposing a list of objects from my database using room:
@Dao
interface MyDao {
@Query("SELECT * FROM myTable")
fun getAllElements(): LiveData<List<Element>>
}
I'd like to be able to observe changes like I normally would using a lifecycle owner using LiveData.observeForever().
Something like:
class BusinessLogicPartOfTheModel(private val myDao: MyDao) {
private var allElements = listOf<Element>()
init {
myDao.getAllElements().observeForever { observedElements ->
allElements = observedElements
}
}
However, I'm finding that if I register an observer like that as well as a more standard observer in a ViewModel and Fragment like 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)
}
}
Only the observer in the fragment is called, and not the observer in the business logic object. I can successfully observe updates in the fragment and pass the events back down to the business logic, but that seems like an incredibly unnecessary level of indirection. Am I missing a step here or is this just unlikely to function the way I want it to?
答案 0 :(得分:2)
您可能应该改用MediatorLiveData。
MediatorLiveData
通过将另一个LiveData
添加到MediatorLiveData
来接受其他事件。
您可以使用类似的
val mediatorLiveData = MediatorLiveData<Item>().apply {
addSource(yourLiveData) {
// do something here
}
}
您还可以查看Transformations。
Transformations
具有Transformation.map()
和Transformation.switchMap()
之类的方法,它们仅在内部使用MediatorLiveData
。