I am new to MVVM pattern, and this is a general question for me but I will use a specific example.
I have:
Place
which contains latitude, longitude, name etc.MapsViewModel
which contains a places list LiveData<List<Place>>
used by the MapsFragment
MapsFragment
which represents the View
of the MVVM pattern.From my understanding the View
should be oblivious of the Model
, in this case MapsFragment
should not know about the Place
model.
I want to populate the Map with markers but markers need latitude and longitude (and other parameters such as name etc.) so i should observe the list of places and map each entry in the list to the marker for it.
I am not sure if I should place the code for mapping places to markers inside a MapsViewModel
so that MapsFragment
can just call mapsViewModel.getMarkers()
and use that marker list to populate the map,
or should the MapsFragment
observe the mapsViewModel.getPlaces()
and from the response map the list to markers and then populate the map.
If the MapsViewModel
is supposed to be responsible for mapping places how will I observe the changes on the LiveData
if new locations are added?
If the MapsFragment
is supposed to be responsible for mapping then doesn't that break the MVVM pattern where Views
should not know about the model?
The example is written in Kotlin
but i did not tag the question with Kotlin
because it is not language specific.
In my current implementations I am observing the places LiveData<List<Place>>
// MapsFragment
...
override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
mapsViewModel.getPlaces().observe(this, Observer { places ->
places?.forEach { place ->
var options = MarkerOptions()
options.position(LatLng(place.lat.toDouble(), place.lon.toDouble()))
mMap.addMarker(options)
}
})
}
...
// MapsViewModel
...
fun getPlaces(): LiveData<List<Place>> {
return Repositories.placesRepository.getPlaces()
}
...
P.S.
One side question for the ListViews and other collection types:
Should every cell have its own ViewModel
or should the whole ListView have only one ViewModel
?
In MVVM architecture, ViewModel
exposes stream of data relevant to the View
. So your View
should definitely observe the list of Place
.
If the MapsFragment is supposed to be responsible for mapping then doesn't that break the MVVM pattern where Views should not know about the model?
We are good, as long as View
is not directly interacting/changing the data layer (Model
) and getting all displayable information from ViewModel
only.
General rule of thumb is,
Data stream exposed by ViewModel
should be simple enough to be directly consumed by the View
.
Hope that answers your question.