Monday, May 3, 2010

Flex4: Best Practices for working with states

Flex4 makes it very easy to write custom components:
1) The data & layout logic can be easily split between a Host Component (data-oriented) and a Skin (layout-oriented).
2) The Host Component can expose public Boolean flags to let the Skin indicate which state should be active.
3) Whenever invalidateSkinState() method is called (either by the system or explicitly by you), overriding the getCurrentSkinState() method based on the Boolean flags allows you complete control over the behaviour.

BUT ... just when we are about to become complacent, all kinds of bugs crawl out of the wood works and we are left wondering ... what happened? This is where the best-practices part comes in:
1) The number of Boolean flags should be equal to the number of states that you component has. (+/-)
[SkinState("normal")]
[SkinState("expanded")]
[SkinState("collapsed")]
[SkinState("disabled")]
...
public class CustomComponentView {
...
   private var _normal:Boolean;
   private var _expanded:Boolean;
   private var _collapsed:Boolean;
   private var _disabled:Boolean;
...
}
2) The Boolean flags themselves should be private or protected and you should expose Bindable public getters and setters for them. (+/-)
private var _normal:Boolean;
...
[Bindable]
public function set normal(value:Boolean):void {
  ...
}
public function get normal():Boolean {
   return _normal;
}
3) The setter methods should always be called with a value of true. (+/-)
There is no point in knowing a state that you don't want to be in, it is far better to know the state that you want to goto. If you wish to enforce this, then place an if statement around your code as follows:
[Bindable]
public function set normal(value:Boolean):void {
  if (value) {
     _normal = value;
     ...
  }
}
4) Each setter should toggle-off the Boolean values for all of the other flags. (+/-)
[Bindable]
public function set normal(value:Boolean):void {
  if (value) {
     _normal = value;
     _expanded = !value;
     _collapsed= !value;
     _disabled= !value;
  }
}


0 comments:

Post a Comment