- Modeling
- Hierarchy
Tree View
If your application calls for it, you can display the hierarchy in a single view.
You probably wouldn't do this for a blog application, but I'll demonstrate how this is done.
Define a specification that starts at the top level, in this case the creator User
of the sites.
Then extend that specification with child specifications in the select
clause.
Continue for as many levels as you would like to display in the tree.
var sitesAndPostsByUser = Given<User>.Match((user, facts) =>
from site in facts.OfType<Site>()
where site.creator == user
where !facts.Any<SiteDeleted>(
sd => sd.site == site &&
!facts.Any<SiteRestored>(sr => sr.deleted == sd))
select new
{
Site = site,
Names =
from name in facts.OfType<SiteName>()
where name.site == site
where !facts.Any<SiteName>(next => next.prior.Contains(name))
select name.value,
Domains =
from domain in facts.OfType<SiteDomain>()
where domain.site == site
where !facts.Any<SiteDomain>(next => next.prior.Contains(domain))
select domain.value,
Posts =
from post in facts.OfType<Post>()
where post.site == site
where !facts.Any<PostDeleted>(pd => pd.post == post &&
!facts.Any<PostRestored>(pr => pr.deleted == pd))
select new
{
Post = post,
Title =
from title in facts.OfType<PostTitle>()
where title.post == post
where !facts.Any<PostTitle>(next => next.prior.Contains(title))
select title.value
}
});
var sitesAndPosts = await jinagaClient.Query(sitesAndPostsByUser, user);
sitesAndPosts
index | value |
---|
0 | { Site = Site { ... }, Names = [ My Journal ], Domains = [ example.com ], Posts = ...
|
Site | Site { creator = Jinaga.User, createdAt = 5/18/2024 5:54:05 PM }
|
creator | Jinaga.User
| createdAt | 2024-05-18 17:54:05Z |
| Names | [ My Journal ]
| Domains | [ example.com ]
| Posts | [ { Post = Post { site = Site { creator = Jinaga.User, createdAt = 5/18/2024 5:54:05 PM }, author = Jinaga.User, createdAt = 5/18/2024 5:54:09 PM }, Title = System.Linq.Enumerable+<OfTypeIterator>d__66`1[System.String] } ]
|
(values) | index | value |
---|
0 | { Post = Post { site = Site { creator = Jinaga.User, createdAt = 5/18/2024 5:54:05 PM }, author = Jinaga.User, createdAt = 5/18/2024 5:54:09 PM }, Title = System.Linq.Enumerable+<OfTypeIterator>d__66`1[System.String] }
|
Post | Post { site = Site { creator = Jinaga.User, createdAt = 5/18/2024 5:54:05 PM }, author = Jinaga.User, createdAt = 5/18/2024 5:54:09 PM }
|
site | Site { creator = Jinaga.User, createdAt = 5/18/2024 5:54:05 PM }
|
creator | Jinaga.User | createdAt | 5/18/2024 5:54:05 PM |
| author | Jinaga.User
|
publicKey | --- FAKE USER --- |
| createdAt | 2024-05-18 17:54:09Z |
| Title | [ Interesting Facts ]
|
|
|
|
|
Create a hierarchical view model by selecting the child view models from the child objects.
var sitesAndPostsViewModel = sitesAndPosts.Select(s => new
{
Name = s.Names.FirstOrDefault() ?? "New site",
Domain = s.Domains.FirstOrDefault() ?? "",
Posts = s.Posts.Select(p => new
{
Title = p.Title.FirstOrDefault() ?? "New post"
})
});
sitesAndPostsViewModel
index | value |
---|
0 | { Name = My Journal, Domain = example.com, Posts = [ { Title = Interesting Facts } ] }
|
Name | | Domain | | Posts | [ { Title = Interesting Facts } ]
|
(values) | index | value |
---|
0 | { Title = Interesting Facts }
|
|
|
|
The hierarchical pattern described here works for models that have different kinds of objects at each level.
If you have a hierarchy that have the same kinds of objects at various levels -- such as folders that contain folders, or employees who manage other employees -- then the pattern is different.
We will discuss that elsewhere.
Continue With
Workflow