Swift MVVM绑定(使用拳击)

时间:2017-06-17 20:08:15

标签: ios swift mvvm

逗人,

我正在尝试使用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所代表的。我需要有人澄清

1 个答案:

答案 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上的属性设置为常规字符串;)