【问题标题】:How do I chain SourceList observation using ReactiveUI and DynamicData?如何使用 ReactiveUI 和 DynamicData 链接 SourceList 观察?
【发布时间】:2019-03-12 08:49:23
【问题描述】:

如果术语被关闭,我们深表歉意;我是一名 iOS 开发人员,必须使用 Xamarin.iOS 来开发应用程序。我正在使用带有 DynamicData 和 MVVM 架构的 ReactiveUI。总的来说,我对 RxSwift 和 FRP 概念相当满意。根据文档,我有一个发布SourceList<MyThing> 的模型,如下所示:

// Property declarations
private readonly SourceList<MyThing> Things;
public IObservableCollection<MyThing> ThingsBindable { get; }

// Later, in the constructor...
Things = new SourceList<MyThing>();
// Is this of the right type?
ThingsBindable = new ObservableCollectionExtended<MyThing>();
Things
    .Connect()
    .Bind(ThingsBindable)
    .Subscribe();

我可以在我的视图(即 iOS 领域的 ViewController)中成功使用 .BindTo() 来获取 UITableView 以在模型更改时更新:

Model
    .WhenAnyValue(model => model.ThingsBindable)
    .BindTo<MyThing, MyThingTableViewCell>(
        tableView,
        new NSString("ThingCellIdentifier"),
        46, // Cell height
        cell => cell.Initialize());  

我希望 ViewModel 订阅并发布(或以其他方式代理)SourceList&lt;MyThing&gt; 或 this 的可绑定版本,而不是直接绑定到模型,以便视图仅使用视图模型属性。 SourceList 在文档中声明为 private;我不确定这里的最佳实践:我是否将其公开并在 ViewModel 中执行我的Connect()?或者有没有办法从 ViewModel 传递公开暴露的IObservableCollection&lt;MyThing&gt; ThingsBindable?我也不相信 ObservableCollectionExtended&lt;MyThing&gt; 是 Bindable 属性的正确类型,但它似乎有效。

我尝试了.ToProperty().Bind().Publish() 等的各种组合,并在 ViewModel 中制作了一个 View-binding Observable 版本,但无济于事,现在我只是将自动完成功能扔到墙上看看什么坚持。任何方向表示赞赏。 TIA。

【问题讨论】:

  • 通常 ReadOnlyObservableCollection 是您用于 Bind() 的类型,但在需要绑定列表支持的 winform 上除外。通常 SourceList 也是私有的,因为它不应该在您的视图中使用。您可以公开 Connect() 方法和它产生的IObservable&lt;IChangeSet&lt;T&gt;&gt;

标签: ios xamarin.ios dynamic-data reactiveui xamarin.ios-binding


【解决方案1】:

我认为这是初学者的误解。这就是我想要的工作方式;也许它会帮助其他 Xamarin.iOS/ReactiveUI/DynamicData 新手。

在我的模型中,我声明了一个私有的SourceList 和一个公开的IObservableList&lt;MyThing&gt;

private readonly SourceList<MyThing> _ModelThings;
public IObservableList<MyThing> ModelThings;

然后在我的构造函数中实例化它们:

_ModelThings = new SourceList<MyThing>();
ModelThings = _Things.AsObservableList();

在我的 ViewModel 中,我声明了一个本地 ObservableCollectionExtended&lt;MyThing&gt; 并将其绑定到模型的公共属性:

public ObservableCollectionExtended<MyThing> ViewModelThings;

// Then, in the constructor:
ViewModelThings = new ObservableCollectionExtended<MyThing>();

model.ModelThings
    .Connect()
    .Bind(ViewModelThings)
    .Subscribe();

在我的 ViewController 中,我将表绑定到 ViewModel.ViewModelThings,如问题所示。如果我想拥有另一个级别的模型,我可以简单地通过 Model.ModelThings.Connect().Bind() 下层,正如 Glenn 在他的评论中暗示的那样。

FWIW,我发现 Roland's Blog(特别是 Observable Lists/Caches 部分)比 GitHub 文档更容易理解。

【讨论】:

  • 出于好奇,您是否看过我们为 RxUI 和 DynamicData 编写的文档? reactiveui.net/docs/handbook/collections
  • 我有!并且一定读了大约 30 遍。但是昨天我看不到的是SourceList&lt;T&gt;.AsObservableList()一起使用。在顶部附近有ObservableCollection&lt;T&gt;.AsObservableList()SourceList&lt;T&gt;.Connect(),但不是我的具体用例。现在重读它,这是有道理的,我可以看到我的作品在页面下方表达。但是对于非 MS Rx (iOS) 开发人员来说,有很多构建块可以尝试在我的脑海中组装并从类似的概念映射(就像 LINQ 提供 map(),但称之为 select()。谁知道呢?)那里!
  • 我正要回答这个问题,我发现它已经被回答了。我同意所说的一切
  • 我也读过很多次文档;特别是collections/DynamicData 部分。我可以找到建议不要继续进行的方法,但我正在努力了解如何进行。这种编码的新手;我会继续加油的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-12
  • 1970-01-01
  • 2021-08-26
  • 1970-01-01
相关资源
最近更新 更多