当一个订阅另一个订阅者时更新两个行为继电器的值的正确方法是什么?

时间:2019-02-02 22:38:51

标签: swift rx-swift

我有两个BehaviorRelay-s,一个绑定到第二个。在一个函数中更新两个值的正确方法是什么? 例如:

class SetupProfileVM {
   let disposeBag = DisposeBag()
   let name= BehaviorRelay<String?>(value: nil)
   let username = BehaviorRelay<String?>(value: nil)

   name.bind(to: username).dispose(by: disposeBag)

   func setNewValues(name: String, username: String) {
       name.accept(name)
       username.accept(username)
   }
}

在这种情况下,我希望当值是由文本字段更新的用户名是相同的用户。但我也需要这个功能来设置新值这两个名称和用户名。这样做的正确方法是什么?我可以确定用户名将首先通过绑定进行更新,然后再通过其新值进行更新吗?

1 个答案:

答案 0 :(得分:0)

我不确定您为什么还要在这里使用BahaviorRelays。对于您所描述的行为,我希望看到类似以下的内容:

struct SetupProfileInputs {
    let nameField: Observable<String>
    let newValues: Observable<(name: String, username: String)>
}

struct SetupProfileVM {

    let name: Observable<String>
    let username: Observable<String>

    init(_ inputs: SetupProfileInputs) {
        name = Observable.merge(inputs.nameField, inputs.newValues.map { $0.name })
        username = Observable.merge(inputs.nameField, inputs.newValues.map { $0.username })
    }
}

或者可能是这样(取决于您使用的是哪种样式的视图模型。)

struct SetupProfileVM {

    struct Inputs {
        let nameField: Observable<String>
        let newValues: Observable<(name: String, username: String)>
    }

    struct Outputs {
        let name: Observable<String>
        let username: Observable<String>
    }

    func transform(_ inputs: Inputs) -> Outputs {
        let name = Observable.merge(inputs.nameField, inputs.newValues.map { $0.name })
        let username = Observable.merge(inputs.nameField, inputs.newValues.map { $0.username })
        return Outputs(name: name, username: username)
    }
}

在任何一种情况下,您都将文本字段附加到nameField输入上。无论调用SetupProfileVM.setNewValues(name:username:)方法是什么,都需要转换为Observable并连接到newValues输入。

执行此操作后,每次更新文本字段时,SetupProfileVM.nameSetupProfileVM.username都会发出相同的值。每当newValues Observable发出一个值时,名称和用户名都会发出不同的值。