State Variables Overview

Table of contents


Introduction

State Variables (SVs) centralize the state handling for MCVS. There are many types of state variables. Here are their common features:

The entire state of the Model is contained in state variables. State variables store the values set by the user and hold the unique values computed by the Model that are displayed in the view. The state of the app, as perceived by the user, can be captured and restored by saving and restoring the values in the appropriate state variables. The operation of the Model-View-Controller system is driven by changes in the state variable state.

New types can be created by inheriting from the StateVar class or its subclasses. All state variable types have a getter/setter method called value. The type of the value is determined by the state variable type. Each SV type is responsible for detecting when its value has changed. For example, an SV type with a primitive value may detect change whenever its value changes. Another SV type with an object type may detect change whenever its value is assigned, even if the assigned object is the same, or it may detect change when one of the object properties changes, etc. Each SV type may also automatically coordinate with the Controller when a change is detected.

Change and SvMonitors.

There are several ways that you can detect when a state variable has changed.
One way is to request that a function be called whenever a change to the SV value is detected using the addChangeListener() method. You can remove the listener using the removeChangeListener() method.

Many SV types also schedule the execution of the Model and/or synchronize the View when a change is detected. This allows a bulk exploration of all changed SVs, as running the Model often changes many state variables. In this case, it’s better to ask whether the state variable value has changed (according to the state variable’s change criteria) since the last time it was interrogated. To help with this, you can request an SvMonitor object using the createMonitor() method. The SvMonitor’s hasChanged() instance method returns true if the state variable value has changed since the last time it was called on this SvMonitor.

State Variable Categories

State variable subclasses fall into different general categories depending on their inheritance tree. Each category shares some common characteristics and may overlap:

SV types can have a name (a String) so that they can be created without reference to an explicit type that would require importing.

Built-in State Variable Types

Here’s a list of SV types built into MVCS:

Public State Variables

Public state variables are published in the global sv namespace and in the namespace sent to each Module computation. Model SVs associated with a Page are always published. In some cases, an SV type will also publish internal child state variables. For example, Unit SV types will publish Number sub-SVs for all units so that they can be accessed independently. This allows the Model to set or get a value in units convenient to it, while the View displays the value in the units desired by the user.

State variable ID strings have the following form: <pageId>_<name> (e.g., 'myPage_total'). If a state variable has internal state variables that it desires to be available, then their IDs are formed from the parent ID with the new sub-name appended to the end after adding another ‘_’ (e.g., 'myPage_weight_kg'). The child state variables, in turn, can also publish sub-names.

State Variable Error Values

There are predefined constants that when assigned to state variable values signal invalid state and can affect the way the SV is displayed in the View:

Custom Error Values

You may define custom error values that have different behavior by creating an instance of class StateVarError. StateVarError is a subclass of Error and has the same signature. By default, the valueOf() method will return cause.errorValue if a cause was specified when the instance was created. Otherwise, it will return NaN. Also by default, the toString() method will return the value of the message property.

Displaying State Variables

Input and Output state variables have an associated Component used to instantiate an input or output element in the View. The View element is automatically synchronized with the value in the State Variable. In TML you can display the state variable using the {{…}} notation. For example:

{{adder_result}}

The template building process uses the StateVar component to turn this shorthand into:

<StateVar sVar=adder_result />

You can specify that the state variable value be displayed as plain text using {{|…|}}, as in:

{{|adder_result|}}

This is a shorthand for:

<StateVar sVar=adder_result valueOnly />

Input SVs only display the text value and do not present user inputs, and Output SVs are not formatted as outputs.

For Unit SV types, you can specify that the unit abbreviation for the current units specified by the unit controller follows the state variable value using {{...@}}. For example:

{{myPage_weight@}}

Would display as “6 kg.” assuming the value is 6 and the current unit controller value is “kg”. This is a shorthand for:

<StateVar sVar=myPage_weight showUnits />

A Number SV that has a unit sub-name or a specific child of a Unit SV can also be used:

{{myPage_weight_kg@}}

If you’d like to display the value and unit abbreviations as text use:

{{|myPage_weight|@}}

or:

{{|myPage_weight@|}}

or:

<StateVar sVar=myPage_weight valueOnly showUnits />

You may also pass additional attributes to the component instance. For example:

{{myPage_weight_kg className=myClassName @}}

CSS Class Names

Each state variable Component instance can also have a className string property.
For example:

{{adder_result className="addrResult1 addrOutput"}}

or equivalently:

<StateVar sVar=adder_result className="addrResult addrOutput" />

In addition, each Input or Output type state variable has a child state variable that contains a class string associated with all Component instances.

When a state variable Component is instantiated, its outermost DOM element will have a className that is the combination of the following:

Most SV types will also have a string of the form svIo_<type>. For example, textInput instances will have svIo_textInput.