【问题标题】:Observables bind 2 textfieldsObservables 绑定 2 个文本字段
【发布时间】:2021-06-18 14:59:57
【问题描述】:

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

  • Observables (我目前正在使用的)
  • 事件总线/通知中心
  • FRP 技术 (ReactiveCocoa / RxSwift)

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

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 中) 与相应的 ViewModel。在我的 ViewController 中有 2 个文本字段(emailInput - passwordInput)和一个“登录”按钮,除非两个文本字段都不为空,否则我希望禁用它。
为此,我添加了两个文本字段的 this 目标:

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 类进行双向绑定?

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

【问题讨论】:

  • 另外,使用.isEmpty 比比较"" 更好
  • 您好,保罗,感谢您的回复。我无法完全理解在 ViewModel 中要做什么,以及如何让我的 ViewModel 在每次文本更改时检查文本字段。

标签: ios swift mvvm data-binding observable


【解决方案1】:

Observable 用于将视图模型的更改传达给视图。您的视图模型无需使用 Observable 模式来响应文本字段中的更新。你可以提供一个简单的函数setCredentials(email: String, password: String)。在此函数中,您可以检查这些值是否为空并设置var loginEnabled: Bindable&lt;Bool&gt;。您的视图会观察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 ?? "")
}

【讨论】:

  • 成功了,谢谢保罗!在等待您的回复时,我发现了一个非常相似的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-27
  • 2023-03-26
相关资源
最近更新 更多