Я очень новичок в RxSwift и RxCocoa, и недавно я интенсивно использовал Variable
из-за того, как удобно просто выводить sh мутации в Variable
через ее значение. Теперь, когда это устарело, я пытаюсь понять, как лучше использовать BehaviorRelay
. Есть Rx-y способ сделать то, что я хочу сделать, но мне тяжело приземлиться на это.
Что я хочу, это поместить экземпляр модели на основе структуры за ViewModel и наблюдать изменения и привязать элементы пользовательского интерфейса таким образом, что я могу изменить эту модель с помощью BehaviorRelay
.
Модель проста:
struct Pizza {
var name: String
var price: Float
}
Так же, как и модель представления:
final class PizzaViewModel {
let pizzaRelay = BehaviorRelay<Pizza>(value: Pizza(name: "Sausage", price: 5.00))
init(pizza: Pizza) {
pizzaRelay.accept(pizza)
// I feel like I'm missing something Rx-like here...
}
}
Тогда где-нибудь вы, возможно, захотите связать UITextField с BehaviorRelay следующим образом:
viewModel
.pizzaRelay
.asObservable()
.map { $0.name }
.bind(to: nameTextField.rx.text)
.disposed(by: disposeBag)
Возникает вопрос: если вам нужно извлечь sh значения из текстового поля обратно в BehaviorRelay, как это должно работать?
nameTextField
.rx
.controlEvent([.editingChanged])
.asObservable()
.subscribe(onNext: { [weak self] in
guard let self = self else { return }
if let text = self.nameTextField.text {
self.viewModel.pizzaRelay.value.name = text // does not compile because value is a let
}
}).disposed(by: disposeBag)
Я, вероятно, не использую правильные типы здесь, или я не думаю в правильной Rx-моде в терминах потоков входов / выходов, но мне любопытно, как другие могут подойти к этой проблеме?
Другие вещи, которые я рассмотрел:
- Просто восстановите новый
Pizza
в .subscribe
, используя текущее значение в BehaviorRelay
, изменив имя и затем .accept
, вернув его обратно в реле. Однако это не совсем правильно. - Создание отдельных
BehaviorRelay
для каждого свойства, которое я хочу изменить в моих Pizza
, затем .accept
-ing-значения для каждого свойства и затем использование combineLatest
на всех этих реле и возврат Observable<Pizza>
. Но это также кажется неуклюжим.
Как это должно работать в идеальном мире? Я думаю об этом неправильно? Помогите! У меня болит голова.