如何使用 RXSwift 和 MVVM 使条件逻辑和重置可观察

How to make condition logic and reset observable with RXSwift and MVVM

我是 RXSwfit 的新手,正在尝试使用 RXSwift 和 MVVM 构建简单的计数应用程序。

查看

  1. 计算标签+按钮被点击的次数。
  2. 增加按钮
  3. 重置按钮

条件

  1. 计数从零开始。
  2. 如果数字达到 10,增加按钮的 isEnabled 应该为 false
  3. 点击重置按钮时,数字应设置为零,如果 + 按钮的 isEnabled 为假,则应设置为真。

所以我创建了 ViewModel,它有一个数字 Observable 作为 BehavioSubject。 以及一些逻辑方法。

   class CounterViewModel {
   
       var number = BehaviorSubject<Int>(value: 0)
    
       func changeCount(_ number: Int) {
           self.number.onNext(number)
       }
    
       func resetCount() {
           //reset number to zero
       }
   }

并且在 ViewController 中,我将 number observable 与 countLabel.text 绑定。

当新数据到达 number observable 时,它​​通过扫描添加新数据,并将结果设置为 countLable.text

当我点击 increaseButton 时,它从 viewModel 调用方法并传递参数 1。

在 changeCount 方法中,它将新数据传递给 observable。

class ViewController: UIViewController {

    @IBOutlet weak var countLabel: UILabel!
    @IBOutlet weak var increaseButton: UIButton!
    @IBOutlet weak var resetButton: UIButton!

    let viewModel = CounterViewModel()
    var disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()
        bind()
    }

    func bind() {
        viewModel.number
        .scan(0, accumulator: +)
        .map { "\([=11=])" }
        .bind(to: countLabel.rx.text)
        .disposed(by: disposeBag)
    }

    @IBAction func increaseButtonPressed(_ sender: Any) {
        viewModel.changeCount(1)
    }

    @IBAction func resetButtonPressed(_ sender: Any) {
        viewModel.resetCount()
      }

}

问题是,

我不知道如何为这个可观察序列设置条件,以及如何重置按钮的数字和状态。

我该怎么做?

我认为如果你像那样在视图控制器中使用扫描运算符,你将无法重置该值。由于您模型中的数字序列不包含当前值。

我想建议您在视图模型中控制增加的逻辑。您的数字序列现在保留当前值,但不像您当前的实现那样只发出一个新数字 1。

然后在视图控制器中,您可以使用相同的序列来控制标签和按钮。

class CounterViewModel {
    var number = BehaviorRelay<Int>(value: 0)

    func increaseCount() {
        number.accept(number.value + 1)
    }

    func resetCount() {
        number.accept(0)
    }
}

现在你的绑定函数将是这样的:

func bind() {
    viewModel.number
        .map { "\([=11=])" }
        .bind(to: countLabel.rx.text)
        .disposed(by: disposeBag)

    viewModel.number
        .map { [=11=] >= 10 ? false : true }
        .bind(to: increaseButton.rx.isEnabled)
        .disposed(by: disposeBag)
}