【问题标题】:Is the View or the ViewModel responsible for transforming data from a Model to be presented in the UI?视图或视图模型是否负责将模型中的数据转换为在 UI 中呈现?
【发布时间】:2019-04-16 12:07:59
【问题描述】:

我是 MVVM 模式的新手,这对我来说是一个普遍的问题,但我将使用一个具体的例子。

我有:

  • 一个数据类Place,包含纬度、经度、名称等。
  • 一个MapsViewModel,其中包含LiveData<List<Place>> 使用的地点列表MapsFragment
  • 还有一个MapsFragment,它代表MVVM 模式的View

据我了解,View 应该忽略 Model,在这种情况下,MapsFragment 不应该知道 Place 模型。

我想用标记填充地图,但标记需要纬度和经度(以及其他参数,例如名称等),所以我应该观察地点列表并将列表中的每个条目映射到它的标记。

我不确定是否应该将用于将地点映射到标记的代码放在MapsViewModel 中,以便MapsFragment 可以调用mapsViewModel.getMarkers() 并使用该标记列表来填充地图, 还是应该 MapsFragment 观察 mapsViewModel.getPlaces() 并从响应映射列表到标记,然后填充映射。

如果MapsViewModel 应该负责映射位置,如果添加了新位置,我将如何观察LiveData 上的变化?

如果MapsFragment 应该负责映射,那么这不会破坏Views 不应该知道模型的MVVM 模式吗?

示例是用Kotlin 编写的,但我没有用Kotlin 标记问​​题,因为它不是特定于语言的。

在我目前的实现中,我正在观察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()
}
...

附: ListViews 和其他集合类型的一个侧面问题: 每个单元格应该有自己的ViewModel 还是整个ListView 应该只有一个ViewModel

【问题讨论】:

  • 不,你的ListViews 不应该有任何ViewModel,因为它们有适配器,并且listviews 数据来自同一个ViewModel 该片段有

标签: android google-maps design-patterns mvvm viewmodel


【解决方案1】:

在 MVVM 架构中,ViewModel 公开与View 相关的数据流。所以你的View一定要注意Place的列表。

如果 MapsFragment 应该负责映射,那么 这不会破坏视图不应该知道的 MVVM 模式 型号?

我们很好,只要View 不直接交互/更改数据层 (Model) 并且仅从 ViewModel 获取所有可显示信息。

一般的经验法则是,
ViewModel 暴露的数据流应该足够简单,可以直接被View 使用。

希望能回答你的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    相关资源
    最近更新 更多