我想知道在以下情况下最佳做法是什么:
name
),其中用户可以编辑特定Model
Observable<Model>
; ViewModel负责从API中检索数据Model
BehaviorRelay
我正在努力寻找解决这个问题的最佳方法:
BehaviorRelay
或类似的我基本上希望有类似于BehaviorRelay
的东西,但是来自Observable
的初始值。订阅(绑定)到BehaviorRelays后,我希望它们从API检索数据。或flatMap
Observable
到BehaviorRelay
?
解决这个问题的最佳方法是什么?
我之前实现过这种方式的方法有其缺点:
BehaviorRelay
,并将状态保留在ViewController中。只需从ViewController订阅ViewModel中的Observable<Model>
并将其绑定到UI。然后,当用户想要保存数据时,从UI(withLatestFrom()
)中检索最新值,并将其作为值传递给ViewModel中的func save(attribute: Value)
。这有效,但我想将所有状态(和业务逻辑)保留在ViewModel中。BehaviorRelay
为空的初始值,然后在ViewModel的init()
中,检索数据并将其绑定到BehaviorRelay
。这意味着在ViewModel中进行订阅,我想避免这种订阅。func refresh() -> Completable
之类的内容,用于设置BehaviorRelay
中do(onNext:)
s中的值。这很有效,但感觉很讨厌。在ViewModel中有let refresh = PublishSubject<()>()
,例如
var model: Observable<Model> {
refresh
.startWith(())
.flatMapLatest { retrieveData() }
}
再次使用do(onNext:)
。与之前的解决方案相同的缺点(感觉很讨厌)。
还有其他办法吗?
答案 0 :(得分:0)
我的第一点是,我认为您需要更多地思考一下ViewModel在MVVM中的作用。 viewmodel的目的是从模型转换/修改数据,使其非常适合在那个屏幕上显示。因此,如果您创建一个充满可编辑字段的屏幕,则ViewModel应该将数据拆分为这些离散字段。在Rx中,这通常意味着为每个字段公开Observable(或者如果需要,可以驱动驱动程序)。目标是为view中的viewmodel simple 中的每个属性绑定。该视图不应该执行属于VM的任何表示转换/逻辑。
你的VM不应该进行任何订阅是正确的,ViewController(在MVVM中查看)将对它所显示的每个字段进行订阅。您可以让viewmodel在调用API时使用.share()
,并使用生成的observable来提供每个字段可观察对象,这样当视图订阅时,它们都不会自己调用API。它们。
我不确定你需要一个BehaviorRelay是指什么。也许你可以澄清那里的需求。如果是因为你想要一种触发刷新的方法,那么你的第四颗子弹就会让人觉得有意义。你可以像这样设置它
让fetchDataTrigger = PublishRelay();
let dataModelObservable = fetchDataTrigger.asObservable()
.startWith(())
.flatMap {
return goCallMyApi()
}
.share()
然后您的每个属性都可以转换dataModelObservable
的输出以生成该字段的值。如果您想触发刷新,只需调用fetchDataTrigger.accept(())
以响应按钮按下或触发刷新的任何内容。