在 RxSwift 中点击 UIView 按钮时,如何在 ViewController 的 viewModel 中执行操作?

How to make action in viewModel of ViewController when in UIView button was tapped in RxSwift?

我有一个类似于自定义弹出窗口的视图,其中有一个按钮。

我在 let tap = button.rx.tap

的帮助下观察点击它

点击此按钮后,我需要在我的 viewModel 中执行操作 - 例如,打印“点击”并将操作推送到中继,但我不明白如何将 whem 绑定在一起。

我尝试在我的 viewModel 中实现它:

let buttonTapped = view.tap
let tapRelay = PublishRelay<Void>

func setTap() {
buttonTapped
.bind { [weak self] _ in {
print("tap")
self?.tapRelay.accept(())
.disposed(by: bag)

所以我的目标是确保按钮上的点击正在进行,但我不知道如何正确执行。

首先,让我们澄清一个误解。视图模型不是您“采取行动”的地方。视图模型是您需要逻辑的地方。您的视图模型中不应有任何中继、主题或观察者。应该是Observables in, Observables out.

其次,在定义 Observable 链时,就像在 Excel 电子表格的单元格中定义公式时,最终结果,即您最终想要做的事情,是最重要的部分但这是你没有描述的一件事。我怀疑你只想打印一些东西。

第三,订阅就像用例一样,由因果关系组成,逻辑将原因转化为结果。逻辑是视图模型中的内容,这里你描述的唯一逻辑是每次点击按钮时“点击”应该是输出。

就目前而言,您描述的整个用例是 “当用户点击按钮时,系统应该打印 'tap'”。“=27=] 只有接下来,我们有一个原因(点击按钮)、逻辑(每次点击一次“点击”一词)和效果(打印一些东西。)可以像这样建模:

// in the view controller or wherever you are keeping effects...
handle(tap: view.tap)
    .subscribe(onNext: { print([=10=]) })
    .disposed(by: disposeBag)

// in the logic portion. This is the "view model"
func handle(tap: Observable<Void>) -> Observable<String> { 
    tap.map { "tap" }
}

我知道上面的代码看起来非常简单。 “这就是 Rx 的全部吗?”你可能在想。 Rx 代码 比您以前编写的任何代码都简单 。您的用例将很明显,一旦掌握了它,它们甚至会更容易。

我知道您的 真实 用例比“打印点击”复杂得多,但是由于您正在查看用例并从程序中提出问题心态,你甚至没有想过包括用例的所有部分。我建议您要么问一个新问题,要么用实际用例更新这个问题。此外,您可能会受益于 joining the RxSwift slack channel,在那里您可以提出许多对于 Stack Overflow 来说太小的小问题。