New Posts New Posts RSS Feed: Editing a collection where the items need to load data depending of the context
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Editing a collection where the items need to load data depending of the context

 Post Reply Post Reply
Author
Walid View Drop Down
Senior Member
Senior Member
Avatar

Joined: 14-Nov-2010
Posts: 161
Post Options Post Options   Quote Walid Quote  Post ReplyReply Direct Link To This Post Topic: Editing a collection where the items need to load data depending of the context
    Posted: 18-Dec-2012 at 9:06am
Hi, 

I wonder what is the best practice with Cocktail when a VM that allows to edit a list (such as address) of items that need to load data depending of the context

Currently, when an Item allow to set a navigation property via a Combobox I use the same collection (located in my ListVM) for all the items. But sometimes I need specific data for each of them.

In this case I see 2 possibilities:
1. Give to ItemVM the guid and it will handle the data loading.
=> Problem, part of the reference data is then in the ListVM, the other in the ItemVM.
      + I dont think there should be any loading (using the uow) in an ItemVM.
2. Create a specific collection in the ItemVM but let the ListVM handle the loading (in the propertyChanged event of the entity for example). Then assigned result to the ItemVM's collection.

I thinks the best solution might be the 2nd one but is this a good way to handle such scenario following the pattern in  Cocktail/Temphire ?

Back to Top
mgood View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
Post Options Post Options   Quote mgood Quote  Post ReplyReply Direct Link To This Post Posted: 18-Dec-2012 at 10:52am
There's nothing wrong with the first option. As long as both VMs share the same uow, the data is in the same place. If you go with option 2 you don't have loose coupling anymore. Your ListVM now needs to understand the logic in the ItemVM and feed it with additional data. It makes more sense to have the ItemVM do all that and be self-contained, so if you reuse the ItemVM in another compositon scenario you don't have to reimplement the loading of the contextual data.
Back to Top
Walid View Drop Down
Senior Member
Senior Member
Avatar

Joined: 14-Nov-2010
Posts: 161
Post Options Post Options   Quote Walid Quote  Post ReplyReply Direct Link To This Post Posted: 18-Dec-2012 at 1:43pm
Ok.

So it's not a problem if the shared collection are now in the Item VM ? It sound more logical but I was afraid to get poor performances if every item had to create his own collection.
Back to Top
mgood View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
Post Options Post Options   Quote mgood Quote  Post ReplyReply Direct Link To This Post Posted: 18-Dec-2012 at 1:55pm
No, it's not. The collection is just a list of pointers. If you have multiple VMs that fetch the same data from a repository, the query cache will make sure it's only fetched once from the datasource and subsequent fetches are satisfied from the cache. 

If you look at TempHire for example all the VMs composed into the DetailVM fetch the StaffingResource. The first fetch will bring it into the cache and the remaining VMs will transparently get it from the cache, so there's no performance hit. Just make sure you don't have more than one VM try fetching the same thing before it is in the cache, otherwise they will all go to the DB. 

You can see this handled in StaffingResourceDetailViewModel.LoadDataAsync. It waits for the staffing resource to be fetched into the cache before calling Start on all the nested VMs.

        private async void LoadDataAsync(Guid staffingResourceId, EditMode editMode)
        {
            using (Busy.GetTicket())
            {
                _unitOfWork = null;
                _staffingResourceId = staffingResourceId;
                EditMode = editMode;

                StaffingResource = await UnitOfWork.StaffingResources.WithIdAsync(staffingResourceId);
                StaffingResourceSummary.Start(StaffingResource.Id, EditMode);
                _sections.ForEach(s => s.Start(StaffingResource.Id, EditMode));
                if (Items.Count == 0)
                {
                    Items.AddRange(_sections.OrderBy(s => s.Index));
                    NotifyOfPropertyChange(() => Items);
                    ActivateItem(Items.First());
                }
            }
        }
Back to Top
mgood View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
Post Options Post Options   Quote mgood Quote  Post ReplyReply Direct Link To This Post Posted: 18-Dec-2012 at 1:58pm
A little caveat I forgot to mention. If the fetch involves a projection then the situation is a little different, because projection queries are not cached. In that case you need to manually make sure that your LineItemVMs retrieve the data from the cache and somewhere higher up make sure the necessary data is loaded into the cache. 
Back to Top
Walid View Drop Down
Senior Member
Senior Member
Avatar

Joined: 14-Nov-2010
Posts: 161
Post Options Post Options   Quote Walid Quote  Post ReplyReply Direct Link To This Post Posted: 18-Dec-2012 at 2:02pm
I am confused, I though the projection weren't in the EntityManager cache
Back to Top
Walid View Drop Down
Senior Member
Senior Member
Avatar

Joined: 14-Nov-2010
Posts: 161
Post Options Post Options   Quote Walid Quote  Post ReplyReply Direct Link To This Post Posted: 18-Dec-2012 at 2:04pm
nevermind I misread your post

Thanks Marcel

Edited by Walid - 18-Dec-2012 at 2:05pm
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down