【问题标题】:Subscription call 2 times, how to unsubscribe observable in RxSwift订阅调用 2 次,如何在 RxSwift 中取消订阅 observable
【发布时间】:2020-10-02 21:41:03
【问题描述】:

重置密码调用发生 2 次,如何删除该块中的订阅。

        let digits = [firstDigit, secondDigit, thirdDigit, fourthDigit, fifthDigit, sixthDigit]
        let digitsValid = digits.map { $0?.textField.rx.text.orEmpty.map({ $0.count == 1 }).share(replay: 1) }
        let allDigitsFilled = Observable.combineLatest(digitsValid.map{ $0 ?? BehaviorRelay(value: false).asObservable()}).share(replay: 1)
        allDigitsFilled.subscribe (onNext: { [weak self] (boolArray) in
            guard let self = self else { return }
            let isFilled = boolArray.allSatisfy({ $0 })
            if isFilled {
                self.viewModel.resetPassword()
            } 
        }).disposed(by: disposeBag)

【问题讨论】:

    标签: swift observable rx-swift subscription


    【解决方案1】:

    每当任何文本字段更改其内容时,都会调用您的 onNext 块。您的第一个目标应该是做到这一点,以便仅在您要重置密码时调用该块。

    首先,您要将.allSatisfy 放在 Observable.filter 调用中,这样您的 onNext 块将仅在所有六个文本字段都包含正好 1 个字符时才会被调用。一旦你这样做了,你就可以简单地使用.take(1),一旦发出下一个值,它将完成订阅。

    这样的东西应该可以做到,而且看起来更干净:

    let digits = [firstDigit, secondDigit, thirdDigit, fourthDigit, fifthDigit, sixthDigit]
    let texts = digits.compactMap { $0?.textField.rx.text.orEmpty }
    Observable.combineLatest(texts)
        .filter { $0.allSatisfy { $0.count == 1 } }
        .map { _ in }
        .take(1)
        .subscribe(onNext: { [viewModel] in
            viewModel?.resetPassword()
        })
        .disposed(by: disposeBag)
    

    【讨论】:

    • 感谢您的帮助!如果填写了文本字段,关于更改第一响应者的任何想法? (按顺序)
    • 是的,每个textField都要监听前一个,当它看到前一个有数据时成为第一响应者。不过,这听起来像是一个不同的问题。要么问一个新问题(一定要先搜索),要么你可以加入 RxSwift slack (slack.rxswift.org)
    猜你喜欢
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-19
    • 2020-08-29
    相关资源
    最近更新 更多