【发布时间】:2018-10-04 13:41:57
【问题描述】:
我想知道在以下情况下最佳做法是什么:
- 项目设置为模型-视图-视图模型
- 我需要显示一个带有文本字段的屏幕(例如
name),用户可以在其中编辑特定Model的详细信息 - ViewModel 包含一个
Observable<Model>; ViewModel 负责从 API 中检索数据 - 视图包含需要使用来自
Model的当前数据预填充的输入字段 - 输入字段需要绑定到例如ViewModel 中的
BehaviorRelays
我正在努力寻找解决此问题的最佳方法:
- 我不想在 ViewModel 中订阅
- 我希望 ViewModel 负责检索数据并填充
BehaviorRelays 或类似名称
我基本上想要一个类似于BehaviorRelays 的东西,但初始值来自Observable。在订阅(绑定) BehaviorRelays 后,我希望他们从 API 中检索数据。还是 flatMap 和 Observable 到 BehaviorRelay?
解决这个问题的最佳方法是什么?
我以前实现过的方法及其缺点:
- 跳过 ViewModel 中的
BehaviorRelays,并将状态保留在 ViewController 中。只需从 ViewController 订阅 ViewModel 中的Observable<Model>并将其绑定到 UI。然后,当用户想要保存数据时,从 UI (withLatestFrom()) 检索最新值并将其作为值传递给 ViewModel 中的func save(attribute: Value)。这可行,但我想将所有状态(和业务逻辑)保留在 ViewModel 中。 - 在ViewModel中,使用
BehaviorRelay,初始值为空,然后在ViewModel的init()中,检索数据并绑定到BehaviorRelays。这意味着在 ViewModel 中有订阅,我想避免这种情况。 - 在 ViewModel 中有类似
func refresh() -> Completable的东西,它将BehaviorRelays 中的值设置在其do(onNext:)中。这行得通,但感觉很老套。 -
在 ViewModel 中有一个
let refresh = PublishSubject<()>(),例如var model: Observable<Model> { refresh .startWith(()) .flatMapLatest { retrieveData() } }再次使用
do(onNext:)。与以前的解决方案相同的缺点(感觉很老套)。 - 在初始化 ViewModel 之前检索数据,并使用模型实例初始化 ViewModel。我不喜欢这种解决方案,因为我希望 ViewModel 负责检索它自己的数据。
还有其他方法吗?
【问题讨论】: