RolandPheasant / DynamicData.Snippets

'101 samples' of dynamic data and rx in action

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Working with 2 dependent ObservableCaches

crosscourt opened this issue · comments

Scenario: Tagging Items
2 caches: SourceCache, SourceCache
When item changes, it needs to go thru the list of tags to determine which one applies to it.
Similarly, when tag changes, retagging needs to occur.

First not so reactive attempt:

var disposable = tagsCache.Connect().Flatten().Subscribe(change =>
{
Tag tag = change.Current;

_itemCache.Edit(u => {
    if (change.Reason == ChangeReason.Remove)
    {
        foreach (Item item in _itemCache.Items.Where(b => b.Tags.Contains(tag)))
        {
            item.Tags.Remove(tag);
            u.AddOrUpdate(item);
        }
    }
    else
    {
        foreach (Item item in _itemCache.Items)
        {
            Tag existingTag = item.Tags.FirstOrDefault(t => t.Id == tag.Id);
            if (existingTag != null)
            {
                item.Tags.Remove(existingTag);
                u.AddOrUpdate(item);
            }

            bool applies = tag.Applies(item);
            if (applies)
            {
                item.Tags.Add(tag);
                u.AddOrUpdate(item);
            }
        }
    }
});

});

var disposable2 = _itemCache.Connect().WhereReasonsAre(ChangeReason.Add, ChangeReason.Update).Flatten().Subscribe(change =>
{
Item item = change.Current;

instance.Tags.Connect().Flatten().Select(i => i.Current).Subscribe(tag =>
{
    if (!item.Tags.Contains(tag) && tag.Applies(item))
    {
        item.Tags.Add(tag);
    }
});

});

From what I can understand you have a source collection with all the items and you want to filter the items into two separate caches?

In that case you can try something like this:

var sourceCacheA = tagSourceCache
                .Connect()
                .Filter(p => p.Title == "tagA")
                .AsObservableCache();
            
var sourceCacheB = tagSourceCache
                .Connect()
                .Filter(p => p.Title == "tagB")
                .AsObservableCache();

sorry for my poor description.
I have 2 separate caches (Items, Tags).

  1. When an item is added/changed/deleted from cache Items, i need to see which Tag will apply to it.
  2. When a Tag is added/changed/deleted, i need to tag the items that are applicable or remove an existing tag from the Items if it no longer applies.

Each tag has a condition, like "Item.Quantity > 10". So any changes to the Item or Tag Condition will need re-evaluation of everything.

Maybe the ForEachChange() operator can come to the rescue