Learning Flex 4 – States

States are easier to work with in Flex 4 than they were with 3. While Flex 3 had the advantage that everything to do with your states was in one place, it made things more complicated by the additional syntax you had to deal with to add/remove items etc. With Flex 4, you can just add your state name to a property to specify a value specific to that state and specify if components should be included in/excluded from a state. The only downside to this is that your state specific code gets scattered but Flash Builder has an option to show you components by state so that helps there.

Starting from the beginning, you first need to declare what states you are going to have. This is done using the <s:states> tag. Within this, specify one or more <s:State> tags with the name property set to the name for your state. The first State is used as the default. In addition to the name, you may also specify a stateGroups property. This allows you to group states so you can refer to the group rather than all the individual states. This could be useful in the case where for most of the time, you want to do the same thing for several states but for specific components/properties you need a finer distinction.

Here’s an example (I like to use all caps for my state names to help them stand out a little more):

<s:State name="LOADING"/>
<s:State name="EMPLOYEE_VIEW" stateGroups="VIEW" />
<s:State name="MANAGER_VIEW" stateGroups="VIEW"/>
<s:State name="MANAGER_SELECT" />

The grouping is a bit artificial in this case but this app starts in the LOADING state while it’s gathering data from the back end. Then, if you’re a manager, the state becomes MANAGER_SELECT where you can select an employee to view data on, finally you get a MANAGER_VIEW of the data or the EMPLOYEE_VIEW if you logged in as an employee. You can see how there might be several components common to the MANAGER_VIEW and the EMPLOYEE_VIEW which you could use the VIEW stateGroup for but some components (maybe a change pay rate button for instance) would be specific to the MANAGER_VIEW.

You can include components in a state by using the property includeIn or exclude them using excludeFrom.  You can specify more than one state by using commas to separate them in the string (or specify a stateGroup). By adding the state to a group container, you can affect all the components within that group.

You can change properties (including event handlers) by suffixing the property name with the state name you want it to apply to eg – label.LOADING="retrieving data..."

If you don’t specify a state, the component/property is considered to be the same for all states. You can change the state by setting the currentState property (by setting it to the empty string, you return to the default or first state).

Custom components can declare their own states and you can use the currentState property of the instance of the custom component to change the state for that particular object.

When the state changes, the enterState event is fired by the State object being entered and by components entering that state. The exitState event is sent by the State and components being left. The object the currentState is being changed on fires currentStateChanging when it’s about to change and currentStateChange when it’s done.

You can use states within a custom item renderer to react to view states such as hovered, selected and change the presentation for these cases. This article has the details. Saturn Boy has also written a blog post looking at states with skinning.