-
Notifications
You must be signed in to change notification settings - Fork 12
View Models
There are certain occasions where we don't want to use the data in the format we have received it from the server, but instead want to manipulate it in some way for a particular view. This is an use case for a ViewModel.
For example, let's assume we have a data table view. We want to use a collection to populate the rows, but also want a summary/total row in the table footer. If our data does not contain summary/total information, we need to calculate this for display purposes only, and this is a time we can use a ViewModel.
In our table view's post-render, we will direct the creation of child views for the table body and table footer:
postRender: function() {
this.addChildren([
{
id: 'AccountTableBodyView',
viewClass: AccountTableBodyView,
options: {
el: this.accountTableBodyElement,
collection: Repository.getBrokerageAccounts()
}
},
{
id: 'AccountTotalsView',
viewClass: AccountTotalsView,
parentElement: this.accountTotalsElement,
options: {
collection: Repository.getBrokerageAccounts()
}
}
]);
}
We pass the same collection into both the table body and the totals view. Then, the totals view creates a viewModel for itself, passing the collection data into it for processing:
initialize: function() {
this.model = new AccountTotalsViewModel(null, {
brokerageAccounts: this.collection
});
this.listenTo(this.model, 'change', this.render);
}
and the ViewModel:
initialize: function(attributes, options) {
this.brokerageAccounts = options.brokerageAccounts;
this.listenTo(this.brokerageAccounts, 'reset', this.calculateTotals);
this.calculateTotals();
}
The ViewModel sets a listener on the collection, so that when it updates, the ViewModel will update itself. The View has also set a listener on the ViewModel, so that when that updates, the view will re-render.
This keeps presentation-only data manipulation away from the data repository, and closer to the view where the data will be displayed.