当我第一次设置登录 View 和使用 Reactive 编程时 - 我无法从我的 ViewContoller 生成信号,该信号将在我的 View 中使用包含我的表单的 Bool 提醒我的 observeValues
监听器验证:
查看文件
viewModel.outputs.loginSuccess
.observeValues { [weak self] value in
print(value)
}
使用我当前的代码 loginSuccess
每次更改电子邮件或密码文本字段时都会触发(我的 View 文件中有 .addTarget
更新我的 MutableProperites我的模型 View 文件)。我遇到麻烦的地方是为 tryLogin
创建一个信号,该信号仅在按下登录按钮时发出,然后映射我的表单验证( emailAndPassword.map(isValid)
),我可以在我的 View 文件中回复。
模型 View 文件
import ReactiveCocoa
import ReactiveSwift
import Result
public protocol LoginViewModelInputs {
/// String value of email textfield text
func emailChanged(_ email: String?)
/// String value of password textfield text
func passwordChanged(_ password: String?)
/// Call when login button is pressed.
func loginButtonTapped()
}
public protocol LoginViewModelOutputs {
/// Emits on login.
var loginSuccess: Signal<(Bool), NoError> { get }
}
public protocol LoginViewModelType {
var inputs: LoginViewModelInputs { get }
var outputs: LoginViewModelOutputs { get }
}
public final class LoginViewModel: LoginViewModelType, LoginViewModelInputs, LoginViewModelOutputs {
public init() {
let emailAndPassword = Signal.combineLatest(
self.emailChangedProperty.signal.skipNil(),
self.passwordChangedProperty.signal.skipNil()
)
let tryLogin = loginButtonTappedProperty.map {
emailAndPassword.map(isValid)
}
self.loginSuccess = tryLogin.value
}
fileprivate let emailChangedProperty = MutableProperty<String?>(nil)
public func emailChanged(_ email: String?) {
self.emailChangedProperty.value = email
}
fileprivate let loginButtonTappedProperty = MutableProperty()
public func loginButtonTapped() {
self.loginButtonTappedProperty.value = ()
}
fileprivate let passwordChangedProperty = MutableProperty<String?>(nil)
public func passwordChanged(_ password: String?) {
self.passwordChangedProperty.value = password
}
public let loginSuccess: Signal<(Bool), NoError>
public var inputs: LoginViewModelInputs { return self }
public var outputs: LoginViewModelOutputs { return self }
}
func isValid(email: String, password: String) -> Bool {
return !email.characters.isEmpty && !password.characters.isEmpty
}
感谢任何帮助。我没有找到很多好的文档来了解信号或观察者,但我可能没找对地方。
最佳答案
这是我会采取的方法
- 根据用户名和密码输入的验证启用和禁用 loginButton
- 将登录 Action 绑定(bind)到按钮事件
代码如下:
let usernameField: UITextField
let passwordField: UITextField
let loginEnabled: MutableProperty<Bool>
let loginButton: UIButton
loginEnabled <~
Signal.combineLatest(
usernameField.reactive.controlEvents(.allEditingEvents),
passwordField.reactive.controlEvents(.allEditingEvents))
.map { _ -> Bool in
return validation()
}
// only allow button to be pressed when validation succeeds
loginButton.reactive.isEnabled <~ loginEnabled
// login action
let loginAction = Action<(String?,String?),Void,NoError> { (username, password) -> SignalProducer<Void, NoError> in
// replace with login procedure
return SignalProducer.empty
}
// bind button event to login action
loginButton.reactive.pressed = CocoaAction(loginAction, input:
(usernameField.text, passwordField.text))
关于swift - 对 MVVM 中的信号使用react?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43032682/