拥有一个由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
每个人。
ViewModel
创建多个订阅是否会产生性能问题?