View models

So far the application consists only of domain entities and domain services. However, the framework also supports view models.

A classic use case is to provide a home page or dashboard, but they are also used to represent certain specific business processes when there isn’t necessarily a domain entity required to track the state of the process itself. Some real-world examples include importing/exporting spreadsheets periodically (eg changes to indexation rates), or generating extracts such as a payment file or summary PDF for an quarterly invoice run.

Dashboard

For this application, though, we’ll just focus on building a dashboard. Moreover, we’ll make this the home page so that it is automatically shown when the user starts up the application.

Our end result is:

dashboard

Solution

git checkout tags/260-view-models
mvn clean package jetty:run

Exercise

  • write a Dashboard view model:

    @DomainObject(
        nature = Nature.VIEW_MODEL,                             (1)
        objectType = "dashboard.Dashboard"
    )
    public class Dashboard {
    
        public String title() { return getOwners().size() + " owners"; }
    
        @CollectionLayout(defaultView = "table")
        public List<Owner> getOwners() {
            return owners.listAll();
        }
    
        @javax.inject.Inject
        Owners owners;
    }
    1 Framework manages the state (though this view model happens to be stateless). For complex view models their state is serialized using JAXB.
  • provide a Dashboard.layout.xml:

    <bs3:grid ...>
        <bs3:row>
            <bs3:col span="12">
                <c:collection id="owners" defaultView="table"/>
            </bs3:col>
        </bs3:row>
        <bs3:row>
            <bs3:col span="0" unreferencedActions="true">
                <c:fieldSet name="Other" unreferencedProperties="true"/>
            </bs3:col>
        </bs3:row>
        <bs3:row>
            <bs3:col span="12">
                <bs3:tabGroup unreferencedCollections="true"/>
            </bs3:col>
        </bs3:row>
    </bs3:grid>

    This example uses the trick of <col span="0"…​> to completely suppress any unreferenced properties or actions (eg those contributed by the framework).

  • implement a HomePageProvider domain service:

    @DomainService(nature = NatureOfService.DOMAIN)
    public class HomePageProvider {
        @HomePage                               (1)
        public Dashboard dashboard() {
            return new Dashboard();
        }
    }
    1 the action annotated with @HomePage is called automatically and its results rendered on the home page. There can only be one action with this annotation.