Observables 绑定 2 个文本字段

Observables bind 2 textfields

所以现在在我正在开发的应用程序中,我决定通过转向 MVVM 设计模式来重构它。在这里,我认识了著名的“Observables”。
在使用 MVVM 时,我设法理解了它们是如何工作的以及它们存在的重要性,我已经阅读了一些关于不同实现技术的解释。我的意思是技术:

我已经这样声明了我的 Bindable class:

import UIKit

class Bindable<T> {
    var value: T? {
        didSet {
            observer?(value)
        }
    }
    
    var observer: ((T?) -> ())?
    
    func bind(observer: @escaping (T?) -> ()) {
        self.observer = observer
    }
    
}

我想做的是绑定 2 个 UITextField 的 (在我的 ViewController's) 与各自的ViewModel。在我的 ViewController 中有 2 个文本字段(emailInput - passwordInput)和一个 'Log In' 按钮,我希望它被禁用,除非两个文本字段都不为空。
为此,我添加了两个文本字段的这个目标:

emailInput.addTarget(self, action: #selector(textFieldDidChange), for: .editingChanged)
passwordInput.addTarget(self, action: #selector(textFieldDidChange), for: .editingChanged)

然后:

/// Enable / Disable --> Log In button
    @objc func textFieldDidChange(_ textField: UITextField) {
        if (emailInput.text == "") || (passwordInput.text == "") {
            logInButton.enableButton(false)
        } else {
            logInButton.enableButton(true)
        }
    }

但我的问题是......我如何在我的 ViewModel 中实现同样的东西??
是否可以使用我的 Bindable class 进行双向绑定?

(如果需要更多代码来解决这个问题,请告诉我,我会编辑问题)

Observable 用于将更改从视图模型传递到视图。您的视图模型无需使用 Observable 模式来响应文本字段中的更新。你可以提供一个简单的函数setCredentials(email: String, password: String)。在此函数中,您可以检查这些值是否为空并设置 var loginEnabled: Bindable<Bool>。您的视图观察 loginEnabled 并相应地设置登录按钮状态。

struct ViewModel {
    var loginEnabled = Bindable<Bool>()
    var email = ""
    var password = ""
    
    init() {
        self.loginEnabled.value = false
    }
    
    func setCredentials(email: String, password: String) {
        self.email = email
        self.password = password
        self.loginEnabled.value = !email.isEmpty && !password.isEmpty
    }
}

然后在你的视图控制器中你有类似

的东西

var viewModel: ViewModel


override func viewDidLoad {
    super.viewDidLoad()
    self.viewModel.loginEnabled.bind { value in 
        self.logInButton.isEnabled = value ?? false
    }
}

@objc func textFieldDidChange(_ textField: UITextField) {
    self.viewModel.setCredentials(email: self.emailInput.text ?? "", password: self.passwordInput.text ?? "")
}