Parts

Parts are the guts of any Potomac application.

A part is quite simply a Flex control that extends mx.core.Containers, typically a Canvas, Box, Panel, etc.

Example of a very simple part:

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300">
     <mx:Metadata>
          [Part(id="myPart",page="myPage",folder="default",title="My Part")]
     </mx:Metadata>	
</mx:Canvas>

Parts will be shown in the page and folder where they’re declared. The type of their parent folder will determine how they’re displayed. For example, in a “tabs” folder the part will be a single tab.

Parts can become much more complicated through the use of PartEvents. All communication between a part and Potomac is done through PartEvents. Some events will be dispatched by Potomac on the part itself. Some events will be dispatched by the part, on itself, typically to inform Potomac of a state change.

PartEvents dispatched by Potomac
partInitialize Initialize is dispatched after the part is created and shown to the user. Typical use for this event is to parse the part’s input (discussed below) and retrieve necessary data.
partDoSave partDoSave events are dispatched when a higher-level action by the user has required that the part be saved. Typically this means that the user is attempting to close the part. partDoSave will only be triggered during close if the part is dirty (discussed below).

To listen to one of these events, a part typically utilizes the [Handles] tag.

Example:

[Handles(event="partInitialize")]
public function init(event:PartEvent):void
{
   ...
}
[Handles(event="partDoSave")]
public function save(event:PartEvent):void
{
  ...
}


There are a variety of PartEvents that the part can dispatch on itself. Potomac listens to these events and performs the associated processing. A part can construct and dispatch these events as normal, or use the one of the PartEvent.send*() methods. Developers are encouraged to use the PartEvent.send* methods.

PartEvents dispatched by Parts
partDirty partDirty is sent when part has been modified by the user and requires a save before the data is persisted.
partClean Dispatched by a part when a dirty part is now clean. Typically dispatched after a successful save.
partBusy Directs Potomac to disable the part and show the busy animation. partBusy is typically dispatched during init and save when an asynchronous service call is triggered.
partIdle Directs Potomac to re-enable a busy part and stop the animation.
partSaveComplete Instructs Potomac that a part’s asynchronous save was successful.
partSaveError Instructs Potomac that a part’s asynchronous save failed.
partSelectionChangeIncoming Instructs Potomac that this part’s selection has changed. See Communicating between Parts
partBroadcastToParts Enables an event to be dispatched on all parts on all pages in Potomac. See Communicating between Parts.



Understanding Inputs

PartInputs are a way for different instances of the same part to work on different data. Many parts in your application won’t require part inputs. Some parts, such as those that show editable forms for database records, will require inputs to provide the identifying information about which item to edit.

A part’s input is contained in the event dispatched during partInitialize.

Parts that are opened automatically have their input set to null.

The input is an optional parameter when opening a part programmatically through Folder#openPart() .

Therefore when creating a form editor part, developers should set open=”false” in their part declarations and open the parts programmatically.

When creating inputs, developers may either extend the PartInput class, or simply attach dynamic properties to a normal PartInput instance as that class is dynamic. In either scenario, the input is intended to be a lightweight descriptor of the content to be retrieved, not the content itself. This is typically a database primary key rather than the entire database record.

When extending the PartInput class, developers must also extend PartInput#equals(). A part id and input combination uniquely identify a part in a folder. Subsequent calls to Folder#openPart using the same part id and input will result in an existing part with that id/input combination being selected rather than a new part being opened.

Example code of opening a part programmatically:

var folder:Folder = ...;
var input:PartInput = new PartInput();
//attach dynamic property
input.primaryKey = 123;
folder.openPart("partID",input);



Understanding the Save Cycle

The save workflow in parts is designed to accommodate asynchronous web services. When a partDoSave event is dispatched on a part, it is asked to initiate its save service. Typically, a developer will also call PartEvent#sendBusy during partDoSave so the UI will show the busy animation.

Potomac will dispatch a partDoSave when the user attempts to close a dirty part. Potomac will not close the part until it receives a partSaveComplete event. If, instead, a partSaveError event is received, Potomac will abort the save process. When a save error has occurred, the part author is expected to provide feedback on the save problems within the part’s UI. It is vital that the developer not use an Alert or other dialog to show this feedback. Potomac may be processing multiple parts during one save cycle and therefore multiple Alert dialogs can stack on top of each other. Instead the developer should provide a UI control within the part itself that shows the error feedback.

Example Save Logic:

public var myHTTPService:HTTPService = ...;
 
[Handles(event="partDoSave")]
public function save(event:PartEvent):void
{
     PartEvent.sendBusy(this,"Saving Record...");
     myHTTPService.send(...);
}
 
[Handles(source="myHTTPService",event="result")]
public function saveSuccess(e:Event):void
{
     PartEvent.sendIdle(this);
     PartEvent.sendSaveComplete(this);
}
 
[Handles(source="myHTTPService",event="fault")]
public function saveError(e:Event):void
{
     PartEvent.sendIdle(this);
     PartEvent.sendSaveError(this);
     errorText.visible = true;
     errorText.text = "Help, I've fallen and I can't get up.  ";
}



Part Title and Icon

A part’s title and icon are set not just by the title and icon declared in the [Part] tag. A part’s title and icon may be overridden by two methods. First, if a part was supplied an input, then the inputs title and icon properties will be checked. This is useful when using inputs that represent different entities. For example, if the part is editing employee records in a database then the title specified in the Part tag may be something vague like “Employee Form”. When creating the input for the part, a developer would set the input.title = “Doe, John”. When the part is created, the title declared in the part will be overridden by the title set in the input.

A part’s title and icon can also be changed dynamically by the part itself. The part’s parent folder respects the assignments to the part’s label and icon (inherited from mx.core.Container). A part may change the title or icon of the part at any time by changing these fields.