RxSwift 与 BehaviorRelay<Any?> 的双向绑定

Posted

技术标签:

【中文标题】RxSwift 与 BehaviorRelay<Any?> 的双向绑定【英文标题】:RxSwift Two way binding with a BehaviorRelay<Any?> 【发布时间】:2018-08-07 08:46:55 【问题描述】:

我创建了一个通用变量。例如,此变量可以连接到 textField 或其他界面元素,例如开关。所以我的变量的类型将是 Any,这样我就可以存储一个 bool、一个字符串或其他东西。

var test: BehaviorRelay<Any?> = BehaviorRelay<Any?>(value: nil)

然后我尝试将我的界面元素连接到这个变量

(self.switch.rx.value <-> viewModel.test).disposed(by: self.disposeBag)

或者

(self.textfield.rx.text <-> viewModel.test).disposed(by: self.disposeBag)

出现此错误Cannot convert value of type 'BehaviorRelay&lt;Any?&gt;' to expected argument type 'BehaviorRelay&lt;Bool&gt;'Cannot convert value of type 'BehaviorRelay&lt;Any?&gt;' to expected argument type 'BehaviorRelay&lt;String?&gt;'

如何使用 RxSwift 做到这一点?

你可以在这里找到我的 func:

infix operator <->
func <-> <T>(property: ControlProperty<T>, variable: BehaviorRelay<T>) -> Disposable         
    let bindToUIDisposable = variable.asObservable()
        .bind(to: property)
    let bindToVariable = property
        .subscribe(onNext:  n in
            variable.accept(n)
        , onCompleted:  
            bindToUIDisposable.dispose()
        )

    return Disposables.create(bindToUIDisposable, bindToVariable)

【问题讨论】:

@duan 我可以问你更多关于你的答案的细节吗? 我不喜欢这种不分青红皂白地使用主题。此外,&lt;-&gt; 可以简化很多。双向使用bind(to:) 而不是subscribe 用于一条路线。 @Charlotte 对不起,这是我的错误,它不会导致无限循环 【参考方案1】:

(在这种情况下,双向绑定不会导致无限循环,因为 UI 元素在以编程方式修改时不会发出值,它们仅在用户更改值时才会发出。如果用户翻转开关,它被推送到主题 [BehaviorRelay],然后将值推回开关,但它在那里结束。)

您必须使用 map 将 Element 转换为 Any? 并映射 Any?从 BehaviorRelay 到 UI 元素时返回到正确的类型。这样做非常笨重且不安全。

最好将 BehaviorRelay 的元素设置为正确的类型。无论如何,你必须知道类型才能对它做任何有用的事情。

【讨论】:

嗨@Daniel T.,我想学习 RxSwift 基础知识和多个视图控制器中的数据传输。你有任何教程吗?你能指导我吗?

以上是关于RxSwift 与 BehaviorRelay<Any?> 的双向绑定的主要内容,如果未能解决你的问题,请参考以下文章

RxSwift : BehaviorRelay 代替变量使用

BehaviorRelay RxSwift 的私有接受

可从多个 BehaviorRelay RxSwift 观察到

使用 Observable 绑定 BehaviorRelay - RxSwift

在 RxSwift 中修改 behaviorRelay 数组内的属性

RxSwift BehaviorRelay auto isDisposed