【发布时间】:2018-06-30 14:14:50
【问题描述】:
跟随 MVVM 时,ViewModel 如何获取对 View 的引用?
例如,一个UITableViewController的VM符合协议UITableViewDelegate,在-didSelectRowAtIndexPath方法中,VM如何调用navigationController.pushViewController等方法?
一个简单的解决方案是在初始化 ViewModel 时传入视图控制器。有没有其他更好的方法来做到这一点?
例如在 viewmodel.swift 中:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let vc = UIStoryboard.Main.instantiateViewController(withIdentifier: "postDetailsVC") as! PQPostDetailsViewController
let cell = collectionView.cellForItem(at: indexPath) as! PQProductCollectionViewCell
vc.featureImage = cell.productImageView.image
// Cannot call the following since ViewModel is not a UIViewController
self.navigationController?.pushViewController(vc, animated: true)
}
【问题讨论】:
-
我以为 UITableViewController 本身已经符合 UITableViewDelegate 了?
-
上面的代码应该是控制器的一部分,而不是视图模型。视图模型应该是惰性的并且是视图子类的一部分。它可以将任何模型对象转换为视图可以理解的格式。
-
@ArunGJ 如果代码进入控制器,它如何根据从网络层检索到的数据自定义单元格,我假设在 ViewModel 中?
-
我相信视图模型应该只负责将数据暴露给视图控制器。您应该将视图模型放在视图控制器/视图中,而不是相反。
-
ViewModel 和 View 正在解耦。这意味着 ViewModel 不知道 View 是什么。它们通过数据绑定进行通信。如果您尝试将视图代码放在 ViewModel 中,那么您做错了并且违反了 MVVM 模式。我建议使用这个库:github.com/duyduong/DDMvvm,它有很多基类供您开始使用 MVVM