问题
right now I am starting to use LiveData for the first time. First I put all of my code in the viewModel including the code to start a search in the server. I used LiveData like this:
Fragment onViewCreated()
viewModel.changeNotifierContacts.observe(this, androidx.lifecycle.Observer { value -> value?.let {
recyclerViewAdapter.setData(value)
} })
This was working as expected. Now I add a repository layer following MVVM pattern. (For this I moved my contact search functionality to repository class) First I implemented the connection between ViewModel and repository like this:
ViewModel code:
fun getContacts(): MutableLiveData<ContactGroup> {
return contactSearchRepository.changeNotifierContacts;
}
fun search(newSearchInput: String) {
contactSearchRepository.searchInRepository(newSearchInput)
}
Now I read this article that told us to not use LiveData like this: https://developer.android.com/topic/libraries/architecture/livedata#merge_livedata
Example from this page:
class MyViewModel(private val repository: PostalCodeRepository) : ViewModel() {
private fun getPostalCode(address: String): LiveData<String> {
// DON'T DO THIS
return repository.getPostCode(address)
}
}
Instead we should use something like this:
var changeNotifierContacts : LiveData<ContactGroup> = Transformations.switchMap(searchInput) {
address -> contactSearchRepository.getPostCode(address) }
Questions:
- Did I understand this article correctly or can I use my first implementation?
- In my constructor of the viewModel I am creating an instance of my repository object that is starting to observe server data and it is getting initial data. (For example I am getting a list of all my friends). I am getting this initial data if I am using my first implementation. If I am using Transformations.switchMap implementation I am not getting this initial data. I first have to start a search here to get updated data then. This is not what I want, I also need to display "my friends" list without doing a search.
- Is there another approach I can use here? Maybe LiveData is not the best solution to connect ViewModel with Repository?
Thanks for responses and suggestions!
回答1:
Did I understand this article correctly or can I use my first implementation?
I think you did, but I believe you have expanded the concept too much.
If you are expecting the user to enter a search to receive an answer, you should do like they said:
class MyViewModel(private val repository: PostalCodeRepository) : ViewModel() {
private val addressInput = MutableLiveData<String>()
val postalCode: LiveData<String> = Transformations.switchMap(addressInput) {
address -> repository.getPostCode(address) }
fun setInput(address: String) {
addressInput.value = address
}
}
However, if you are loading a default list, you should do it like you did in your first example:
val getContact = contactSearchRepository.changeNotifierContacts
In this case you will have to observe getContact and postalCode.
In my constructor of the viewModel I am creating an instance of my repository object that is starting to observe server data and it is getting initial data. (For example I am getting a list of all my friends). I am getting this initial data if I am using my first implementation. If I am using Transformations.switchMap implementation I am not getting this initial data. I first have to start a search here to get updated data then. This is not what I want, I also need to display "my friends" list without doing a search.
You can start your fragment/activity with a default search, like this:
MyViewModel.setInput("Friends")
This way you do not need to observe two objects as postalCode will provide all answers.
Is there another approach I can use here? Maybe LiveData is not the best solution to connect ViewModel with Repository?
I think live data is your answer. After done with the learning curve it becomes easier to deal with!
I hope it helps!
来源:https://stackoverflow.com/questions/61748362/how-to-use-livedata-with-transformations-switchmap-correctly-to-get-initial-data