ViewModelable
ViewModelable 是一个轻量级的 模型-视图-视图模型 模式实现,适用于 iOS,且不依赖外部库。MVVM 模式通常与响应式扩展一起用于绑定,但并非总是如此。在这种情况下,视图模型的作用是分离任何非 UI 代码,使其远离视图控制器。每个 UIViewController
都有一个对应的视图模型实例。视图模型中的业务逻辑应该始终能够创建初始状态,无论设备状态如何(即使在没有互联网连接的情况下,视图模型也应该是有效的)。
每个视图模型都应该有输入变量和输出变量,这些变量根据输入或本地缓存进行填充。输出变量通常应该是必需的。
其核心思想是,在 ViewModel
上的所有输出都始终定义为初始化,以便在 UIViewController
显示时使用,独立于设备状态、网络连接或类似错误状态。 这也使得对视图模型进行单元测试变得容易。
视图模型有 5 种状态
- 初始化
- 设置
- 加载数据
- 数据已加载
- 卸载数据
状态变更依次遵循以下路径
初始化 -> 设置 -> 加载数据 -> 数据已加载 -> 更新 -> 卸载数据 -> 设置*
数据已加载的状态可以接收多个回调,但视图模型不能返回到初始化状态。
视图模型通过观察者模式(类似于代理)通知视图控制器状态变更。观察者收到的方法
func viewModelDidSetup (viewModel: ViewModel)
func viewModelWillLoad (viewModel: ViewModel)
func viewModelDidLoad (viewModel: ViewModel)
func viewModelDidUpdate (viewModel: ViewModel, updates: [String : AnyObject])
func viewModelWillUnload (viewModel: ViewModel)
func viewModelDidUnload (viewModel: ViewModel)
您还可以使用 .state
属性检查视图模型的状态。状态转换是异步的,因为视图模型通常与异步操作一起使用。回调不一定发生在主线程上,因此请务必正确使用 dispatch。
示例
以下示例实现了一个简单的汽车视图模型,不使用具体的模型对象。
class CarViewModel : ViewModel {
// MARK: Input
var make : String?
var model : String?
// MARK: Output
private(set) var horsePower : Double = 0.0
private(set) var weight : Double = 0.0
func updateOutput() {
guard let make = make, model = model else {
horsePower = 0.0
weight = 0.0
return
}
if make == "Lamborgihini" && model == "Huracan" {
horsePower = 782
weight = 2100
}
else {
horsePower = 120
weight = 1100
}
}
}
为视图模型实现的简单视图控制器。
class CarViewController : ModelableViewController<CarViewModel>, ViewModelObservable {
//
// MARK: ViewModelObservable
//
func viewModelDidLoad (viewModel: ViewModel) {
//
// Update screen properties
//
// self.textLabel.text = "\(self.viewModel.horsePower) kW"
}
}
联系
Dal Rupnik
- legoless 在 GitHub
- @thelegoless 在 Twitter
- [email ;.
许可证
ViewModelable 在 MIT 许可下可用。有关更多信息,请参阅 LICENSE 文件。