逗人,
我正在尝试使用Boxing实现MVVM架构模式。我只是通过添加拳击课来完成它:
class Dynamic<T> {
typealias Listener = (T) -> Void
var listener: Listener?
func bind(listener: Listener?) {
self.listener = listener
}
func bindAndFire(listener: Listener?) {
self.listener = listener
listener?(value)
}
var value: T {
didSet {
listener?(value)
}
}
init(_ v: T) {
value = v
}}
然后在ViewController中我引用了一个ViewModel,这是我的View Controller:
class SignUpViewController: UIViewController {
// UI Outlets
@IBOutlet weak var emailLoginTextField: FloatLabelTextField!
@IBOutlet weak var passwordLoginTextField: FloatLabelTextField!
var viewModel = AuthenticationViewModel()
override func viewDidLoad() {
super.viewDidLoad()
viewModel.user.email.bind{
self.emailLoginTextField.text = $0
}
}}
这是我的视图模型:
class AuthenticationViewModel{
let defaults = UserDefaults.standard
let serviceManager = ServiceManager()
var user = User()
func signupUser(email : String?, password: String?){
let parameters : [String:String] = ["email":emailField, "password": password!, "system": "ios"]
serviceManager.initWithPOSTConnection(server: Utitlites.getServerName(), parameters: parameters, methodName: "/api/user/register", completion: { (responseData , errorMessage) -> Void in
let json = (responseData as AnyObject) as! JSON
print(json)
if ErrorHandling.handleErrorMessage(responseData: responseData).0 == true {
self.defaults.set("userId", forKey: json["user"]["id"].stringValue)
//self.userId.value = json["user"]["id"].stringValue
self.user = User(json: json)
}
})
}}
这是我的模特:
class User{
var id = Dynamic("")
var name = Dynamic("")
var email = Dynamic("")
init(){
}
init(json: JSON){
id.value = json["user"]["id"].stringValue
email.value = json["user"]["email"].stringValue
}}
我的问题是:
MVVM架构明智,使用ViewController中的这一行访问模型是正确的:
viewModel.user.email.bind{
self.emailLoginTextField.text = $0
}
因为我现在可以看到View正在访问模型,我认为这不是MVVM所代表的。我需要有人澄清
答案 0 :(得分:2)
这个(imo)的最佳做法是根据31:18
的{{1}}来实际设置Model
是私有的,你的VC不需要完全了解它,只知道ViewModel
。
之后,为Model
中的ViewModel
设置getter,如下所示:
var id: Dynamic<String> = Dynamic("")
var name: Dynamic<String> = Dynamic("")
var email: Dynamic<String> = Dynamic("")
然后,在您的ViewModel
中,将User对象设置为didSet
通知程序,以便相应地更新ViewModel
的数据:
private var user = User() {
didSet {
id = user.id
name = user.name
email = user.email
}
}
现在,您只能直接从ViewModel
而不是Model
访问这些属性:
viewModel.email.bind{
self.emailLoginTextField.text = $0
}
哦,不要忘记将Model
上的属性设置为常规字符串;)