通过使用RX填充ObservableCollection

时间:2013-12-04 12:59:42

标签: c# windows-phone-8 system.reactive

我想知道是否可以使用RX解决以下情况?

我有一个REST服务调用,它有一个输入参数距离并加载数据,这个数据被插入到ViewModel的ObservableCollection中,以便View显示数据... 像这样的伪代码:

public async Task<int> LoadData(int distance)
{ 
    this.ListOnUI.Clear();
    var dataList = await Task.Run(() => _dataService.GetListAsync(distance));
    foreach(var dataItem in dataList)
    {
       this.ListOnUI.Add(dataItem);
    }
    return dataList.Count;
}

现在,这个小代码片段被包装在一个方法中,该方法返回dataList的计数。 我对该计数做了什么,检查返回的金额是否至少为20,如果不是,我记得距离较远的方法。

这个设置有什么问题...

  1. 每次调用该方法时,都会清除UI列表
  2. 用户有时需要等待很长时间才能达到20项
  3. 虽然我们还没有达到20个项目,但UI会清除列表
  4. 所以我的直觉告诉我这可以通过某种方式使用RX来解决,这样我们就可以“加载”加载/添加UI列表。

    但是我对RX的了解并不足以解决它...所以任何想法?

    备注:当我们调用LoadData服务时,我们得到一个JSON字符串,然后映射到DataItems的集合,所以如果我们不清除UI ObservableCollection并且只是在每次迭代时添加它们...我们会得到同一个项目在列表中多次,因为它是新构造的对象(尽管具有相同的数据)。

3 个答案:

答案 0 :(得分:1)

数据对象中是否有任何Key?如果是这样,你可以检查你的foreach,而对象已经被包含,只有在它没有时才添加它。这样你就不必清除它(连同所有副作用)。

如果没有密钥,您可以通过散列标题+距离或您拥有的任何数据字段来创建一个密钥,这些数据字段可以唯一地标识您的数据项并将其用于检查。

不知道有没有更好的反应性扩展方法,但它应该至少解决你的情况。

答案 1 :(得分:1)

修改为每次计算列表增量。要使包正常工作,您只需要在GetListAsync返回的项目上适当地实现Equals。也许是通过SB Dev建议的人为关键比较。不确定在问题的背景下Rx能带来多少。

    public async Task<int> LoadData(int distance)
    {
        int count = 0;
        IList<object> dataList = null;
        while (count < 20)
        {
            dataList = await Task.Run(() => _dataService.GetListAsync(distance));
            count = dataList.Count;
            var newItems = dataList.Except(ListOnUI).ToList();
            var removedItems = ListOnUI.Except(dataList).ToList();                
            removedItems.ForEach(x => ListOnUI.Remove(x));
            newItems.ForEach(ListOnUI.Add);
        }
        return count;
    }

假设您使用ObservableCollection作为列表,请参阅Sort ObservableCollection - what is the best approach?进行排序。

答案 2 :(得分:0)

感谢建议的答案,它让我考虑使用Sortable Observable集合,只是在它们进来时添加项目!

我在这里使用了Andrea解释的例子:http://www.xamlplayground.org/post/2010/04/27/Keeping-an-ObservableCollection-sorted-with-a-method-override.aspx

但是使用了博客文章评论中提到的二进制搜索选项! 为了确保我们在列表中已经找到项目时不停止代码,我只是注释掉了Throw Exception。

为此,我只需要实现IComparable。