如何更新由Observable

时间:2018-04-25 11:36:57

标签: c# system.reactive reactive

拥有一个由observable填充的ObservableCollection,我想知道如果已经存在,更新集合中项目ViewModel的最有效和正确的方法是什么。我想出了两个解决方案:

解决方案1 ​​

让MainViewModel负责识别ObservableCollection中是否已存在该项,如果是,则执行更新:

MainViewModel.cs

private readonly SortedObservableCollection<IConversationPreviewViewModel> _conversationPreviews = new SortedObservableCollection<IConversationPreviewViewModel>();

public void SubscribeOnConversations()
{
    _observeConversationsUseCase
        .Conversations
        .ObserveOn(_schedulerProvider.Dispatcher)
        .Subscribe(OnNext);
}

private void OnNext(Conversation conversation)
{
    var previewViewModel = _conversationPreviews.FirstOrDefault(it => it.ConversationId == conversation.ConversationId);
    if (previewViewModel == null)
    {
        IConversationPreviewViewModel conversationPreview = _conversationPreviewFactory.Create(conversation);
        _conversationPreviews.Add(conversationPreview);
    }
    else
    {
        previewViewModel.UpdateConversation(conversation);
    }
}

解决方案2

主视图模型仅负责添加新项目,但更新是每个项目视图模型本身的责任,将每个项目订阅到observable:

   public class Conversation
        {
            public int Id { get; set; }

            public string Name { get; set; }
        }

public class ConversationItemViewModel
        {
            private int Id { get; set; }

            public string Text { get; private set; }

            public ConversationItemViewModel(Conversation conversation, ObserveConversations observeConversations)
            {
                Id = conversation.Id;
                Text = conversation.Name;

                PrintStatus("ctor");

                observeConversations.Conversations.Where(it => it.Id == Id).Subscribe(OnNext);
            }

            private void OnNext(Conversation conversation)
            {
                Text = conversation.Name;

                PrintStatus("OnNext");
            }

            private void PrintStatus(string from)
            {
                Console.WriteLine($"Id:{Id} Text:{Text} From: {from}");
            }
        }

   public class ObserveConversations
        {
            public IConnectableObservable<Conversation> Conversations { get; }

            public ObserveConversations()
            {
                Conversations = ConversationsArriving();

                Conversations.Connect();
            }

            public IConnectableObservable<Conversation> ConversationsArriving()
            {
                var list = new List<Conversation>() { new Conversation(){Id = 1, Name = "name1"},
                    new Conversation() {Id = 2, Name = "name2" },
                    new Conversation() {Id = 3, Name = "name3"},
                    new Conversation() {Id = 2, Name = "updatedname2"}, // Update this
                    new Conversation() {Id = 4, Name = "name4"},
                    new Conversation() {Id = 3, Name = "updatedname3"}, // Update this
                };

                return list.ToObservable().Delay(TimeSpan.FromSeconds(1)).Publish();
            }
        }

        public class MainViewModel
        {
            private readonly ObserveConversations _observeConversations;

            public MainViewModel(ObserveConversations observeConversations)
            {
                _observeConversations = observeConversations;
            }

            private ObservableCollection<ConversationItemViewModel> ConversationItemViewModels { get; } = new ObservableCollection<ConversationItemViewModel>();

            public void Start()
            {
                _observeConversations.Conversations
                    .Distinct(it => it.Id)
                    .Subscribe(OnNext);
            }

            private void OnNext(Conversation conversation)
            {
                ConversationItemViewModels.Add(new ConversationItemViewModel(conversation, _observeConversations));
            }
        }

class Program
{
    static void Main(string[] args)
    {
        var observeConversations = new ObserveConversations();
        var mainViewModel = new MainViewModel(observeConversations);
        mainViewModel.Start();

        Console.ReadLine();
    }

就个人而言,我发现解决方案2更好,因为它将更新的责任委托给每个ViewModel每个人。

  1. 是否有比那些更精细的解决方案?
  2. 为解决方案2中的每个项ViewModel创建多个订阅是否会产生性能问题?

0 个答案:

没有答案