3

UIViewController和我的视图模型存在依赖性问题。viewDidLoad基本上我想在我的视图模型中收听事件。目前我有一个Class A实例化视图模型并UIViewController带有参数的viewModel,所以:

let viewModel = ViewModel()
let viewController = UIViewController(viewModel)

我已经为以下内容创建了一个 RxCocoa 扩展viewDidLoad

var viewDidLoad: Observable<Void> {
    return self.sentMessage(#selector(Base.viewDidLoad)).map { _ in Void() }
}

现在我坚持将它绑定rx.viewDidLoad到我的视图模型中的一个可观察对象。我能够做到这一点,Subjects但我想要一种仅使用Observable. 我知道我可以rx.viewDidLoad作为视图模型的构造函数参数注入,但这样我会破坏我的架构,我不想允许在UIViewController内部实例化视图模型,但我想将其保留为注入的依赖项。

有什么建议么?谢谢

解决方案

感谢@tomahh,我使用了这个解决方案:

我的视图控制器:

override func configure(viewModel: ViewModel) {
    viewModel.bindViewDidLoad(rx.viewDidLoad)
}

我的视图模型:

func bindViewDidLoad(_ viewControllerDidLoad: Observable<Void>) {
    //Create observers which depend on viewControllerDidLoad
}
4

3 回答 3

4

因为ViewController已经知道视图模型,它可以ViewModel在初始化时设置一个属性

class ViewController: UIViewController {
  init(_ viewModel: ViewModel) {
    viewModel.viewDidLoad = self.rx.viewDidLoad
  }
}

然后,可以将 in 中的 observablesViewModel定义为计算属性派生viewDidLoad

struct ViewModel {
  var viewDidLoad: Observable<Void> = .never()

  var something: Observable<String> {
     return viewDidLoad.map { "Huhu, something is guuut" }
  }
}
于 2017-02-19T09:14:10.823 回答
2

如果有人需要这里的 rx 属性,这是一个随时可用的解决方案,受@marco-santarossa 代码的启发

extension Reactive where Base: UIView {
    var willMoveToWindow: Observable<Bool> {
        return self.sentMessage(#selector(Base.willMove(toWindow:)))
            .map({ $0.filter({ !($0 is NSNull) }) })
            .map({ $0.isEmpty == false })
    }
    var viewWillAppear: Observable<Void> {
        return self.willMoveToWindow
            .filter({ $0 })
            .map({ _ in Void() })
    }
    var viewWillDisappear: Observable<Void> {
        return self.willMoveToWindow
            .filter({ !$0 })
            .map({ _ in Void() })
    }
}
于 2019-12-16T11:54:20.227 回答
1
let viewDidAppear = rx.sentMessage(#selector(UIViewController.viewDidAppear(_:)))
        .mapToVoid()
        .asDriver(onErrorJustReturn: ())
于 2020-11-25T21:59:42.673 回答