如何使用 RXSwift 和 MVVM 使条件逻辑和重置可观察
How to make condition logic and reset observable with RXSwift and MVVM
我是 RXSwfit 的新手,正在尝试使用 RXSwift 和 MVVM 构建简单的计数应用程序。
查看
- 计算标签+按钮被点击的次数。
- 增加按钮
- 重置按钮
条件
- 计数从零开始。
- 如果数字达到 10,增加按钮的 isEnabled 应该为 false
- 点击重置按钮时,数字应设置为零,如果 + 按钮的 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)
}
我是 RXSwfit 的新手,正在尝试使用 RXSwift 和 MVVM 构建简单的计数应用程序。
查看
- 计算标签+按钮被点击的次数。
- 增加按钮
- 重置按钮
条件
- 计数从零开始。
- 如果数字达到 10,增加按钮的 isEnabled 应该为 false
- 点击重置按钮时,数字应设置为零,如果 + 按钮的 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)
}