ios - 在 Swift 中为 MVVM 模式创建一个可观察的变量
问题描述
我试图观察一个变量的变化。下面的代码有效,但是当我设置isValid
观察者的初始值时被触发。然后在 my 之后再次设置callAPI()
变量。isValid
所以我的部分逻辑代码正在过早地被检查。
实现观察者的正确方法是什么,以便在初始加载时不会触发值的初始设置?
我做这一切都错了吗?有没有更好的办法?
视图控制器
class SomeViewController: UIViewController {
private let viewModel = SignInViewModel()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// I want to watch this variable, but when it is initialized, it's already false and fires off the bad() func
viewModel.isValid.bind {[weak self] isValid in
if(isValid){
self?.good()
} else {
self?.bad()
}
}
viewModel.callAPI()
}
private func bad(){
print("VALID --")
}
private func bad(){
print("-- NOT VALID")
}
}
我的视图模型
public class SomeViewModel {
lazy var isValid = Observer(false)
func callAPI(){
// Do something on the background and set the boolean
isValid.value = //result
}
}
观察者
final class Observer<T> {
typealias Listener = (T) -> Void
var listener: Listener?
var value: T {
didSet {
listener?(value)
}
}
init(_ value: T) {
self.value = value
}
func bind(listener: Listener?) {
self.listener = listener
listener?(value)
}
}
解决方案
您可以listener
通过修改Observer
为以下内容来避免最初的火灾:
final class Observer<T> {
typealias Listener = (T) -> Void
var listener: Listener?
var value: T {
didSet {
listener?(value)
}
}
init(_ value: T) {
self.value = value
}
func bind(listener: Listener?) {
self.listener = listener
}
func bindAndFire(listener: Listener?) {
self.listener = listener
listener?(value)
}
}
调用bind(listener:)
函数只会添加新的监听器而不立即调用它,而调用bindAndFire(listener:)
也会触发监听器的初始值。
或者您可以在函数中使用Bool
参数bind(listener:)
来确定您是否想要为初始值触发侦听器:
func bind(fire: Bool = false, listener: Listener?) {
self.listener = listener
if fire {
listener?(value)
}
}
推荐阅读
- sql-server - Spring批处理中ExecutorType BATCH的情况下,没有收到插入主键
- swift - SwiftUI:同步手势生效时视图自动移动
- google-cloud-platform - 如何通过云监控或任何其他方式获取 Google Cloud Spanner 和 Cloud Bigtable 的服务器端错误率指标
- go - 几个 esutil.BulkIndexer 可以共享一个 elasticsearch.Client 吗?
- reactjs - 类型错误:js_cookie__WEBPACK_IMPORTED_MODULE_4___default.a.getJSON 不是函数
- docker - 对容器和 Docker 层表示感到困惑
- flutter - 如何在颤动中使用挑选的图像作为背景图像?
- yarnpkg - 嵌套包的选择性解析语法
- cypress - 如何使用柏树单击具有特定内容的 div 内的按钮?
- bash - Replcae \n 使用带有新行的 sed