使用RxSwift和Realm实现MVVM - 双向绑定

时间:2018-04-08 15:22:25

标签: swift mvvm data-binding realm rx-swift

我使用RxSwift,Realm和RxRealm实现MVVM模式如下所示:

MVVM pattern with realm and RxSwift

E.g。我有一个显示一些可编辑内容的文本字段。我希望这个实时保存/同步到DB这样:

//View
textField.rx.text.subscribe(textViewModel.saveText.inputs)
viewModel.stringValue.drive(textField.rx.text)

//ViewModel:
lazy var saveText = Action<String,Void>{ newStringValue in 
   realm.write{
     textObject.stringValue = newStringValue
   }
  //don't block the main thread
  return Observable.just()
}  

lazy var stringValue = Observable(from:textObject).map{$0.stringValue}.asDriver(onErrorJustReturn : "no string")

在TextField中慢慢输入时,一切都有效。当打字非常快速思考时,信件会被吞噬掉#34;像这样:

  1. 输入&#34; A&#34;
  2. 写&#34; A&#34;到DB
  3. 键入&#34; B&#34;
  4. 接收&#34; A&#34;来自DB - &GT; Textfield值变为A而不是AB。
  5. 使用实时同步时,这是所需的行为。对于单文本输入,这似乎不是一个好的解决方案。如何正确实现这样的双向绑定并避免不希望的效果,特别是在viewModel在写入之前或从源读取之后处理文本值的情况下?

1 个答案:

答案 0 :(得分:1)

在您的要求中,Realm存储的数据是否会通过其他来源更新?如你所知,你能否收到来自另一个领域的字符串中的值?

如果没有,那么您可以信任您的输入,并且您的写入最终可以保持一致。

但问题在于写入速度和返回数据的通知;小但不是没有。也许中间人会有益。

例如,将输入字段写入将定期与Realm同步的值。这样,您的observable可以立即访问更新的值,您可以相信最终的值将是

很高兴进一步探索,看看我们是否可以解决问题。 :)

修改

Realm对conflict resolution的指导。

手动方法可能是持有两个值;一个是您开始使用的值,另一个是服务器管理的值。

如果起始值和服务器值不同,则需要管理冲突。根据数据的复杂程度,您的策略可以是拒绝一个,接受一个或以某种方式合并它们。