我有一个名为
LoginViewController
的视图控制器。
LoginViewController.swiftimport UIKit
class LoginViewController: UIViewController {
@IBOutlet private var usernameTextField: UITextField!
@IBOutlet private var passwordTextField: UITextField!
private let loginViewModel = LoginViewModel()
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func loginButtonPressed(sender: UIButton) {
loginViewModel.login()
}
}
它没有一个 Model 类。但我创建了一个叫做 LoginViewModel
的视图模型,用于放置验证逻辑和网络调用。
LoginViewModel.swift
import Foundation
class LoginViewModel {
var username: String?
var password: String?
init(username: String? = nil, password: String? = nil) {
self.username = username
self.password = password
}
func validate() {
if username == nil || password == nil {
// Show the user an alert with the error
}
}
func login() {
// Call the login() method in ApiHandler
let api = ApiHandler()
api.login(username!, password: password!, success: { (data) -> Void in
// Go to the next view controller
}) { (error) -> Void in
// Show the user an alert with the error
}
}
}
我的第一个问题是,我的MVVM实现是否正确?我对此有疑问的原因是,例如我将登录按钮的点击事件(
loginButtonPressed
)放在了控制器中。我没有为登录屏幕创建单独的视图,因为它只有几个文本字段和一个按钮。控制器是否可以拥有与UI元素绑定的事件方法是可接受的?我的下一个问题也与登录按钮有关。当用户点击该按钮时,应该将用户名和密码值传递到LoginViewModel进行验证,如果成功,则传递到API调用。我的问题是如何将这些值传递给视图模型。我应该向
login()
方法添加两个参数,并在从视图控制器调用该方法时传递它们吗?还是应该在视图模型中声明属性,并从视图控制器设置它们的值?哪个在MVVM中是可以接受的?接下来看一下视图模型中的
validate()
方法。如果它们中的任何一个为空,用户应该得到通知。这意味着在检查之后,应将结果返回到视图控制器以采取必要的操作(显示警报)。login()
方法也是同样的情况。如果请求失败,请向用户发出警报,如果成功,则转到下一个视图控制器。如何从视图模型向控制器通知这些事件?在这种情况下是否可以使用类似KVO的绑定机制?在iOS中使用MVVM时,还有哪些绑定机制?KVO是其中之一。但我读到它并不适用于较大的项目,因为它需要大量重复代码(注册/注销观察者等)。还有哪些其他选项?我知道ReactiveCocoa是用于此的框架,但我想看看是否有其他本地选项。
我在互联网上找到的所有关于MVVM的材料几乎没有提供我想要澄清的这些部分的信息,因此我非常感谢您的回答。