Radical Documentation
View on GitHub
release-2
release-2
  • Home
  • Presentation
    • AbstractViewModel
    • Conventions
      • Bootstrap Conventions
      • Runtime Conventions
      • Conventions override
    • Commands and DelegateCommand
    • IViewResolver
      • Default view behaviors
      • view life cycle events
        • Callback expectations
        • notify messages
    • Message broker MVVM built-in messages
    • Application boot process
      • Application configuration
      • Application shutdown
      • Singleton applications
    • AbstractMementoViewModel
      • Simple ViewModel graphs
      • Collections and complex ViewModel graphs
    • Validation and Validation Services
    • Resources
      • Services as resources
      • ViewModels as resources
    • UI Composition
      • Region content lifecycle
      • TabControl region
      • Create a custom region
  • Concepts
    • Inversion of Control
      • Third party DI containers
    • Entities
      • Property System
    • Messaging and Message Broker
      • POCO messages
      • Standalone message handlers
    • Observers
      • PropertyObserver
      • MementoObserver
      • BrokerObserver
  • Memento
    • Change Tracking Service
      • MementoEntity and MementoEntityCollection
      • Handling change tracking:
        • Simple model
        • Collections
        • Complex objects graph
      • Atomic operations
      • Change Tracking Service API
      • Property Metadata for the ChangeTrackingService
      • Handling collection sync
      • Property State
  • Behaviors
    • DataGrid Behaviors
    • Password
    • Generic routed event handler to command behavior
    • Overlay adorner
      • Busy status manager
    • TextBox behaviors:
      • Command
      • Auto select
      • DisableUndoManager (.Net 3.5 only)
  • Markup Extensions
    • Editor binding
    • Auto Command binding
  • How to
    • Get the view of a given view model
    • Bi-directional communication between different windows/views
    • Handle the busy status during async/long running operations
    • Implement a customer improvement program
    • Manage focus
    • Create a splash screen
    • Access view model after view is closed
    • Intercept ViewModels before they are used
  • Upgrade guides
    • Radical Presentation 1.x to Radical 2.x for .NET Core
Powered by GitBook
On this page
  1. Memento
  2. Change Tracking Service

Handling collection sync

We have seen how to handle change tracking in MVVM based editor loading the editor given a graph of objects coming from a persistent storage.

What we still miss is the ability to correlate changes back to the persistent graph. Radical does not offer any out-of-the-box automatic support to achieve this requirement but if we think about it the only thing not so easy to deal with are collections.

For class model instances, such as a Person and its PersonViewModel editor it is straightforward at save time simply copy back all the properties from the ViewModel to the model.

On the other hand for collection of objects, where the collection is tracked by the ChangeTrackingService we need to understand what has happened to the collection structure in order to:

  • Items added to the edited collection need to be created in the underlying data store or simply added to the persistent model;

  • Items removed from the edited collection should be deleted from the underlying data store or simply removed from the persistent model;

  • Items changed in the edited collection needs to be simply synched back to their corresponding counterpart in the persistent model;

We can leverage the power of change tracking IAdvisory to understand what has happened during the editing phase:

var advisory = service.GetAdvisory();
var items = advisory.Where( a =>
{
    return a.Target.GetType().Is<Address>() 
       && a.Action == ProposedActions.Delete;
} )
.Select( a => a.Target );

In the above snippet we are retrieving an advisory that is the list of proposed actions that the memento service think we should do to align the in memory model with a persistent storage. We are expecting that in the list of the tracked entities there is an Address class type and we are filtering Address instances looking only for items that should be deleted, that means that have been removed from a memento collection.

Since the above snippet is not really handy we set up a bunch of extension methods for the ChangeTrackingService component to support what we think are the most interesting use cases:

  • Extensions are defined in the Topics.Radical.ChangeTracking namespace;

  • GetNewItems<T>() retrieve the list of added items of the given type T;

  • GetChangedItems<T>() retrieve the list of changed items of the given type T that were already exiting;

  • GetDeletedItems<T>() retrieve the list of deleted items of the given type T;

  • GetRemovedItems<T>() retrieve the list of removed items of the given type T;

Using extension methods the above snippet can be rewritten as:

var items = service.GetDeletedItems<Address>();

Deleted and Removed items

What is the difference between deleted items and removed items?

  • Deleted items are items that we initially load into the collection, we can call them persistent, that were removed during the editing phase;

  • Removed items are items that were created during the editing phase, transient items, and then removed from the collections, most of the time this type of items can be safely ignored since their existence do not affect the persistent storage;

PreviousProperty Metadata for the ChangeTrackingServiceNextProperty State

Last updated 4 years ago