【发布时间】:2020-11-21 13:03:54
【问题描述】:
所以在 MVVM 架构中,即使在 google 示例中,我们也可以看到如下内容:
class CharacterListActivity :BaseActivity() {
val ViewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.getData() // Bad!!!
...
viewModel.state.observe(this) { state ->
when(state) { // handling state is not views job
Success -> { navigatetoNextPage() } // navigating is not views job
Progress -> { showProgress() }
NetworkError -> { ShowSnackbar(viewModel.error) } // I,m not sure about this one either
Error -> { showErrorDialog(viewModel.error)
}
}
我们知道,任何架构都有自己的规则,这些规则使代码随着时间的推移可测试、可维护和可扩展。 根据Wikipedia 和Microsoft docs 在MVVM 模式中,这是视图:
视图是用户在屏幕上看到的结构、布局和外观。[6]它显示模型的表示并接收用户与视图的交互(点击、键盘、手势等),并通过数据绑定(属性、事件回调等)将这些处理转发给视图模型。被定义为链接视图和视图模型。
每个视图都在 XAML 中定义,具有不包含业务逻辑的有限代码隐藏。但是,在某些情况下,代码隐藏可能包含 UI 逻辑,用于实现动画等视觉行为。
XAML 是 Xamarin 的东西,所以现在让我们回到我们的代码:
在这里,由于activity 决定如何处理state,活动就像在MVC 中的Controller 一样工作,但是活动应该是View,视图只是应该做UI 逻辑。
该活动甚至告诉ViewModel 获取数据。这又不是View 的工作。
请注意,告诉代码中的其他模块做什么不是视图的工作。这使视图充当控制器。视图应该通过来自 ViewModel 的回调来处理其状态。
View 应该只是告诉ViewModel 像onClick() 这样的事件。
由于 ViewModel 无权访问 View,因此无法显示对话框或直接在应用中导航!
那么在不违反架构规则的情况下,有什么替代方法可以做到这一点?我是否应该为 ViewModel 中的任何生命周期事件提供函数,例如 viewModel.onCreate? 或 viewModel.onStart?导航或显示对话框呢?
为了记录我没有混淆 mvc 和 mvvm,我是说这种模式可以,推荐购买 google。
这不是基于意见的,当然任何人都可以拥有自己的任何架构实现,但必须始终遵循规则以实现加班可维护性。
我可以为你一一命名这段代码中的违规行为:
1) UI 不负责获取数据,UI 只需要将事件告诉 ViewModel。
2) UI 不负责处理状态,这正是它在这里所做的。更一般地说,UI 不应包含任何非 UI 逻辑。
3) UI 不负责在屏幕之间导航
【问题讨论】:
-
您可以在 ViewModel 的
init块中使用getData() -
是的,但情况并非总是如此
标签: android kotlin mvvm viewmodel android-viewmodel