In this first article, we going to look at using DojoX MVC to define our application Models, showing the use of the new StatefulModel class. Later in the series, we’ll look at binding our defined Model to a View template, rendering the HTML output and hooking into user events.
Further details on the StatefulModel class can be found here.
Defining a Model
Reviewing the TodoMVC specification, our application Model needs to contain a list of todo tasks, each one containing a description and that task’s completed state. The task’s description will be provided by the user and can later be modified. As the task is completed, the task’s internal state must be updated. Representing the todo tasks as an array of objects will allow binding to a Repeat View, having a HTML template rendered for each task in the Model.
Looking at the application, there’s two additional properties in the View that are derived from other Model attributes, counts for the completed and remaining tasks. To allow automatic binding of these values into our View template, we’re going to represent these directly in our model. Later on, we’ll set up binding between Model values to allow those composite values to be calculated automatically.
1 2 3 4 5 6 7 8 9 10 11 12
Binding to Model changes
Once you’ve defined a model, you’ll want to be notified of any attribute changes. Using Dojo Stateful’s “watch” method, we can register a function to be executed whenever that model’s attributes are modified using the getter & setter pattern.
The dojox.mvc.Bind module extends this functionality to cover two common patterns, listening to changes on a series of attributes and binding model properties together. The “bindInputs” function allows an array of model attributes to be passed in, executing a callback whenever any of the attributes change.
More usefully, the “bind” function sets up a one way coupling between a source and destination model attribute. Whenever the source attribute value changes, the destination model attribute will be automatically updated with the same result. If you want to transform the source value before it’s updated in the destination model, an optional function callback can be passed in. This will be called with the new attribute value and the return value used to update the destination model.
1 2 3
Creating composite model values
In the TodoMVC application our model has two attributes, “remaining” & “completed”, that need to computed automatically from other model values.
Calculating the “completed” total is performed by looping through the “todos” array and counting the tasks which have an “isDone” attribute as true. Whenever a task’s “isDone” value changes we want to re-calculate and update the “completed” total. Whenever a new task is added, we automatically bind the new item to our calculating function, which updates the composite value with the new count if any of our model tasks are modified.
1 2 3 4 5 6 7 8 9
Once we have the “completed” total, the “remaining” attribute can be easily calculated if we know the total number of tasks. Using the “bind” method ensures this happens automatically, using optional transform function to create the new composite value.
1 2 3
Defining our Model requires application code to declare the composite (completed, remaining) attributes, bind to changes on the current (and future) todo tasks and deal with persisting data to local storage. Rather than having this code in the application controller, we can extend the StatefulModel class to encapsulate all this logic. Using Dojo’s Declare module, we can create a new class which extends StatefulModel, allowing us to set the initial model properties as class attributes rather than having to call the dojox.mvc.newStatefulModel() factory manually. The skeleton outline for our StatefulModel extension is shown below, we’ve removed some internal methods for brevity.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
Unfortunately, it doesn’t contain code for automatically populating the initial model from the “store” property, this is handled in the “dojox.mvc.newStatefulModel” factory. Therefore, we manually construct the initial model values from the store, if available, and re-call the “_createModel” function in our constructor.
Once the model has been instantiated, we can declare and initialise our composite model bindings as well as binding to the initial todo tasks pulled from persistent storage.
You can see the source code for the final version of the TodoModel class here.
In this first article, we’ve reviewed how to use DojoX MVC’s StatefulModel class to create application Models that we can later bind to Views within the application. Using the StatefulModel class, we can bind to model properties, having callbacks executed when one or more attribute values changed.
Taking this further, we can bind model properties together, creating dynamic models whose properties automatically update as others change. Combining this functionality, we defined composite model attributes for the “completed” and “remaining” properties that were automatically calculated as the todo tasks’ state changed, wrapping this code within an extension of the StatefulModel class.
Next time, we’ll be looking at another component of the MVC pattern, Views. Using the TodoMVC application as our example, we’ll show how to define View templates, bind our Model with the View to generate the application’s HTML and ensure user interactions with the todo tasks automatically update the Model.