ios - 在 MVVM 中设置委托的正确方法
问题描述
我想知道在 Swift 的 MVVM 模式中的 ViewModel 中设置委托的正确方法是什么。
我正在从另一个类实例化 ViewController:
let viewModel = DashboardViewModel()
let viewController = DashboardViewController(viewModel: viewModel)
我的视图模型:
protocol DashboardViewModelType {
var items: [Item] { get }
var reloadDelegate: DashboardDataReloadDelegate? { get set }
}
protocol DashboardDataReloadDelegate: class {
func reloadData()
}
class DashboardViewModel: DashboardViewModelType {
var items: [Item] = []
weak var reloadDelegate: DashboardDataReloadDelegate?
init() {
loadItems()
}
func loadItems() {
let databaseFetcher = DatabaseDaysFetcher()
databaseFetcher.getDays(onData: { (items) in
self.items = items
reloadDelegate?.reloadData() //delegate is nil here
}) { (error) in
print(error)
}
}
}
和视图控制器:
class DashboardViewController: UIViewController {
var viewModel: DashboardViewModelType?
init(viewModel: DashboardViewModelType) {
self.viewModel = viewModel
super.init(nibName: nil, bundle: nil)
self.viewModel!.reloadDelegate = self // it is executed after
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension DashboardViewController: DashboardDataReloadDelegate {
func reloadData() {
print("data reloaded")
}
}
所以主要问题是,如果我想在另一个类中注入 viewModel,我会在委托尚未设置时实例化 viewModel。loadItems
在协议内部声明DashboardViewModelType
,然后从 ViewController 内部的 init 或 viewDidLoad 调用此函数会更好吗?
解决方案
是的,您可以注入for the DatabaseDaysFetcher
,然后如您所说,转到协议。init
DashboardViewModel
loadItems
DashboardViewModelType
然后当你调用时loadItems
,它应该回调给调用者。loadItems
然后在回调中使用 [weak self] 。
这将否定对delegate
.
protocol DashboardViewModelType {
init(databaseFetcher: DatabaseDaysFetcher)
func loadItems(completion: ([Item]) -> Void, error: (Error) -> Void)
}
final class DashboardViewModel: DashboardViewModelType {
private var databaseFetcher: DatabaseDaysFetcher
init(databaseFetcher: DatabaseDaysFetcher) {
self.databaseFetcher = databaseFetcher
}
func loadItems(completion: ([Item]) -> Void, onError: (Error) -> Void) {
self.databaseFetcher.getDays(onData: { (items) in
completion(items)
}) { (error) in
onError(error)
}
}
}
推荐阅读
- android - 如何计算android中日期范围材料选择器之间的天数
- html - 图像和容器 div 以不正确的宽度呈现
- validation - 来自不同电子表格的数据验证范围
- go - 无法在 go 中声明嵌入式结构的字段
- java - 避免 WorkManager 立即运行?
- php - 一个新手 PHP 问题 - 从 URL 中隐藏 PHP 变量
- php - 在 PHP 数组赋值中抛出一个奇怪的错误
- python - 如何更改导致烧瓶中的 TypeError 的 Python 函数
- web - 无法连接到我的应用程序服务器上的本地主机,但可以通过网络访问它
- prestashop - prestashop 自定义计算添加到基本价格