Skip to content

Instantly share code, notes, and snippets.

@RolandPheasant
Last active April 18, 2017 20:57
Show Gist options
  • Save RolandPheasant/4c178c879c6cd0abf8c71af53a7d9311 to your computer and use it in GitHub Desktop.
Save RolandPheasant/4c178c879c6cd0abf8c71af53a7d9311 to your computer and use it in GitHub Desktop.
/// <summary>
/// Transforms the without updates. Blah Blah
/// </summary>
/// <typeparam name="TObject">The type of the object.</typeparam>
/// <typeparam name="TKey">The type of the key.</typeparam>
/// <typeparam name="TDestination">The type of the destination.</typeparam>
/// <param name="source">The source.</param>
/// <param name="factory">The factory.</param>
/// <param name="updateAction">Apply changes to the original. Example (original, newitem) => original.Value = newitem.Value </param>
/// <returns></returns>
public static IObservable<IChangeSet<TDestination, TKey>> TransformWithoutUpdates<TObject, TKey, TDestination>(this IObservable<IChangeSet<TObject, TKey>> source,
Func<TObject, TDestination> factory,
Action<TDestination, TDestination> updateAction)
{
return Observable.Create<IChangeSet<TDestination, TKey>>(observer =>
{
var shared = source
.Transform(factory)
.Publish();
//create cache which never replaces the original item
var nonUpdatingObservableCache = shared
.WhereReasonsAreNot(ChangeReason.Update)
.AsObservableCache();
//transform the result and manually update original items
var withoutUpdates = shared
.Select(changes =>
{
var altered = new List<Change<TDestination, TKey>>(changes.Count);
foreach (var change in changes)
switch (change.Reason)
{
case ChangeReason.Update:
//get the original from the non-updating cache
var original = nonUpdatingObservableCache.Lookup(change.Key)
.ValueOrThrow(() => new Exception("There should always be something matching the key"));
//directly update original view model
var updated = change.Current;
updateAction(original, updated);
//evaluate is a command to operators to self-requery when there are in-line changes [should automatically re-sort]
altered.Add(new Change<TDestination, TKey>(ChangeReason.Evaluate, change.Key, original));
break;
default:
altered.Add(change);
break;
}
return new ChangeSet<TDestination, TKey>(altered);
})
.SubscribeSafe(observer);
return new CompositeDisposable(withoutUpdates, shared.Connect(), nonUpdatingObservableCache);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment