Top Banner
Copyright 2009 Tikal Knowledge, Ltd. | 1 | Creating Custom Creating Custom Components in Flex 3 Components in Flex 3
34

Building Components In Flex3

Dec 19, 2014

Download

Technology

Tikal Knowledge

Building Components in Flex3 is the topic of July 2009's Flex group meeting @ tikalk
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 1 |

Creating Custom Components Creating Custom Components in Flex 3in Flex 3

Page 2: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 2 |

Vocab Lesson Vocab Lesson

Flex Component Lifecycle» A mechanism the framework uses to create, manage and destroy

components» A mechanism that makes the most of the player rendering model.

Halo: Component architecture used in Flex 3 and earlier versions.

Page 3: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 3 |

Halo Component Architecture Patterns Halo Component Architecture Patterns

Defining Patterns in Halo» Invalidation/Validation Model

• Methodology to aggregate changes and defer work until an optimal later time

» Event Driven Interaction Model • Inform the component if something is about to or has

already occurred » Composition

• Parameterization of a component’s appearance or content.

• Most often occurs through factories and item renderers.

Page 4: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 4 |

Invalidation / Validation theoryInvalidation / Validation theory

Flash player Rendering model

Page 5: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 5 |

Flash player framesFlash player frames

The Flash Player runs through each frame of a timeline one by one at a speed determined by the frame rate (fps)

Each frame consists of executing ActionScript code and rendering

FP5 allow executing actionscript when a particular events occur

EnterFrame is fired when a frame begins

Frame rate is configurable (compiled with the swf) but is limited by browser/Os

Page 6: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 6 |

Flash player framesFlash player frames

On one hand : Flex application consists on 2 frames

On the other hand : enterFrame event is continuously fired

? Question ?

Page 7: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 7 |

Flash player framesFlash player frames

! Answer !

Page 8: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 8 |

The Elastic Racetrack The Elastic Racetrack

Flex component lifecycle is built atop this frame model

Invalidation/Validation takes advantage of the elastic racetrack to get work done in an efficient manner.

Images courtesy of Sean Christmann

Traditional Flash Player Elastic Racetrack

Page 9: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 9 |

The Elastic Racetrack The Elastic Racetrack

Images courtesy of Sean Christmann

User Actions• Interact with any non- validation events from this frame (mouse movements,timers, ENTER_FRAMEs etc.)• Dispatch invalidation events(invalidateProperties etc.)

Invalidate Action• Process all validation calls(CommitProperties)

Render Action• Do the heavy lifting - actually draw on the screen

Event.updateAfterEvent -> Stage.Invalidate->Render event->Validation methods

Page 10: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 10 |

Deferred Validation ModelDeferred Validation Model

Waiting for update request

Waiting for update request

Update Requested

Update Requested

InvalidationInvalidation

ValidationValidation

Validation occurs right before Rendering

Invalidation

Validation

Page 11: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 11 |

Halo Component Lifecycle – Broken Down Halo Component Lifecycle – Broken Down

3 Phase Lifecycle1. Initialization (Birth)

• Construction• Configuration• Attachment• Initialization

2. Updating (Life)• Component responds to changes by using the

Invalidation/Validation Model - Interaction -> invalidation - > validation

3. Destruction (Death)• Out of sight, out of mind • Detachment • Garbage collection

Page 12: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 12 |

Consider this component:Consider this component:

public class A extends UIComponent

{

public function A() {

trace( "CONSTRUCTOR" );

super();

}

override protected function createChildren() : void {

trace( "CREATECHILDREN" );

super.createChildren();

}

override protected function measure() : void {

trace( "MEASURE" );

super.measure();

}

override protected function updateDisplayList(width:Number, height:Number) : void {

trace( "UPDATEDISPLAYLIST" );

super.updateDisplayList(width,height);

}

override protected function commitProperties():void {

trace( "COMMITPROPERTIES" );

super.commitProperties();

}

Page 13: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 13 |

Lifecycle Phase 1: Initialization Lifecycle Phase 1: Initialization

Construction: Component begins its lifecycle » Component is instantiated (create in memory),

through the new operator in ActionScript or in MXML» No required arguments (if it will be used in MXML);

zero, or all optional » Calls super() to invoke superclass constructor; if you

don’t, the compiler will!» Constructor can add event listeners, hard code

initialization properties of super classes» Have access to class properties and methods» Children have not yet been created!» Minimal work should occur here (not JIT’ed).» Don’t create or attach children in the constructor

Construction

Configuration

Attachment

Initialization

Invalidation

Validation

Detachment

Garbage Collection

Initialization

(Born)

Updating(Life)

Destruction

(Death)

Page 14: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 14 |

Lifecycle Phase 1: Initialization Lifecycle Phase 1: Initialization

Configuration: Component properties are set internally to be processed later» In MXML, properties are assigned in this

phase, before children are attached or initialized.

Sample.mxml wants to expose a text property to update the label

<mx:Canvas>

<mx:Label id="myLabel"/>

</mx:Canvas>

Construction

Configuration

Attachment

Initialization

Invalidation

Validation

Detachment

Garbage Collection

Initialization

(Born)

Updating(Life)

Destruction

(Death)

<mx:Application ...>...

<local:Sample text="value!"/></mx:Application>

Output:Sample constructorSample.text setterAdding Sample to display list (which creates myLabel)

Page 15: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 15 |

Lifecycle Phase 1: Initialization Lifecycle Phase 1: Initialization

» Properties must expect that children haven’t been created yet.Construction

Configuration

Attachment

Initialization

Invalidation

Validation

Detachment

Garbage Collection

Initialization

(Born)

Updating(Life)

Destruction

(Death)

Bad:public function set text(value:String):void}

myLabel.text = value;// Possible Error! during first config phase,// myLabel might not exist!

{

Page 16: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 16 |

Lifecycle Phase 1: Initialization Lifecycle Phase 1: Initialization

» In ActionScript, properties might be assigned in this phase, before children are attached or initialized

Construction

Configuration

Attachment

Initialization

Invalidation

Validation

Detachment

Garbage Collection

Initialization

(Born)

Updating(Life)

Destruction

(Death)

//Developer might code this: var comp: SampleChild = new SampleChild(); addChild(comp); comp.property1 = value1; //off the hook

//Or this: var comp: SampleChild = new SampleChild(); comp.property1 = value1; //throw exception addChild(comp);

Exception in case the property try to

access a child

Page 17: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 17 |

Lifecycle Phase 1: Initialization Lifecycle Phase 1: Initialization

» To avoid performance bottlenecks, make your setters fast and defer any real work until validation using invalidatin/validation

Construction

Configuration

Attachment

Initialization

Invalidation

Validation

Detachment

Garbage Collection

Initialization

(Born)

Updating(Life)

Destruction

(Death)

Good :private var _text:String = "";private var textChanged:boolean = false;public function set text(value:String):void}

_text = value; //storetextChanged = true; //markinvalidateProperties(); //invalidateinvalidateSize();invalidateDisplayList();

}override protected function commitProperties():void{

super.commitProperties();if(textChanged){ myLabel.text = text; textChanged = false;} //don’t forget to unmark !!!

{}

Page 18: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 18 |

Lifecycle Phase 1: Initialization Lifecycle Phase 1: Initialization

Attachment: Addition to the display list

Component is added to the display list through addChild, addChildAt, MXML declaration.

Without attachment, component lifecycle will stall.

Construction

Configuration

Attachment

Initialization

Invalidation

Validation

Detachment

Garbage Collection

Initialization

(Born)

Updating(Life)

Destruction

(Death)<mx:Application ...>

<mx:Script><![CDATA[override protected function createChildren() : void {

super.createChildren();var a : A = new A(); Output: CONSTRUCTORthis.addChild( a ); CREATECHILDREN

} ]]></mx:Script>

</mx:Application>

COMMITPROPERTIESMEASUREUPDATEDISPLAYLISTCREATIONCOMPLETE

Moral of the story: don’t add components to the stage until you need them.

Page 19: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 19 |

Lifecycle Phase 1: Initialization Lifecycle Phase 1: Initialization

Initialization main steps ( not all of them ! full list)

1.preinitialize event is dispatched2.createChildren() is called3.Calling invalidation methods4.initialize event is dispatched 5.First full validation pass occurs6.creationComplete event is dispatched

Full invalidation/validation cycle is invoked (we will come back to this)

Construction

Configuration

Attachment

Initialization

Invalidation

Validation

Detachment

Garbage Collection

Initialization

(Born)

Updating(Life)

Destruction

(Death)

Create

Validate

Page 20: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 20 |

Lifecycle Phase 1: Initialization Lifecycle Phase 1: Initialization

createChildren() - The attachment workhorse » Ideal place for adding children that are required

throughout the lifetime of the component » Dynamic or data-driven children which should be added

in commitProperties() » Check to make sure the children have not been

instantiated already» Follow the same pattern Flex uses: construct, configure,

attach. if (!stopButton)

}

stopButton = new Button();

stopButton.label = "stop";

stopButton.addEventListener(MouseEvent.CLICK,stopBtnClickHandler);

controlBar.addChild(stopButton);

{

Construction

Configuration

Attachment

Initialization

Invalidation

Validation

Detachment

Garbage Collection

Initialization

(Born)

Updating(Life)

Destruction

(Death)

Construct

Configure

Attach

Page 21: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 21 |

Lifecycle Phase 1: Initialization Lifecycle Phase 1: Initialization

First full invalidation/validation pass occurs here» Invalidation is captured by 3 methods:

• invalidateProperties()• invalidateSize()• invalidateDisplayList()

» Validation is captured by 3 methods:• commitProperties()• measure()• updateDisplayList()

Phase 1 Done!

Construction

Configuration

Attachment

Initialization

Invalidation

Validation

Detachment

Garbage Collection

Initialization

(Born)

Updating(Life)

Destruction

(Death)

Page 22: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 22 |

Phase 2: UpdatingPhase 2: Updating

Our component has been created!

It’s a living, breathing entity, and now it needs to know how to update.

Updates occur» When a user interacts with a component» When methods or properties are invoked/set

A component should use Flex’s Invalidation/Validation Model to respond to changes.

Construction

Configuration

Attachment

Initialization

Invalidation

Validation

Detachment

Garbage Collection

Initialization

(Born)

Updating(Life)

Destruction

(Death)

Page 23: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 23 |

Deferred Validation Model: An Optimization Deferred Validation Model: An Optimization

Invalidation/validation model is split into 3 phases:

Update component properties

Update sizing & measurement information

Update drawing and positioning

invalidateProperties()

invalidateSize()

invalidateDisplayList()

commitProperties()

measure()

updateDisplayList()

Page 24: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 24 |

commitProperties()commitProperties()

Property management phase of validation» Purpose: Commit values typically set

using a property setter» Invoked by the framework before

measurement and layout. » There is a definite pattern that should be

followed in order to avoid extra work. • Dirty flags and storage variables

» This is the place to add/remove children not required through the life of the entire component (as opposed to createChildren())

Construction

Configuration

Attachment

Initialization

Invalidation

Validation

Detachment

Garbage Collection

Initialization

(Born)

Updating(Life)

Destruction

(Death)

Page 25: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 25 |

Invalidation/Validation exampleInvalidation/Validation example

The idea : bind a list of labels to an array. The list will add a label to the display list for each item in the array.

<mx:Application>

<mx:Script>

<![CDATA[

import mx.collections.ArrayCollection;

[Bindable]

public var arr : ArrayCollection = new ArrayCollection();

public function onClick() : void

{

var c : int = 0;

while( c++ < 20 )

{

arr.addItem( c ); //add 20 items to the array collection

}

}

]]>

</mx:Script>

<mx:VBox>

<mx:Button label="Click me!" click="onClick()"/>

<test:BadList id="theList" dataProvider="{arr}"/> //the list creates a label for each entity in the array

</mx:VBox>

</mx:Application>

Page 26: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 26 |

Invalidation/Validation Bad implementation Invalidation/Validation Bad implementation public class BadList extends VBox

}

private var _dataProvider : ArrayCollection;

public function set dataProvider( arr : ArrayCollection ) : void

{

this._dataProvider = arr;

arr.addEventListener( CollectionEvent.COLLECTION_CHANGE, dataProviderChangeHandler );

}

private function dataProviderChangeHandler( e : Event ) : void

{

this.removeAllChildren();

for each( var n : Number in this._dataProvider )

{

var l : Label = new Label();

l.text = n.toString();

this.addChild( l );

}

}

} Result: dataProviderChangeHandler called 20 times

Page 27: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 27 |

Invalidation/Validation Good implementation Invalidation/Validation Good implementation public class GoodList extends VBox

}

private var _dataProvider : ArrayCollection;

private var _dataProviderChanged : Boolean = false;

public function set dataProvider( arr : ArrayCollection ) : void {

This.dataProvider = arr;

arr.addEventListener( CollectionEvent.COLLECTION_CHANGE, dataProviderChangeHandler );

dataProviderChanged = true;

invalidateProperties();

}

override protected function commitProperties():void {

super.commitProperties();

if( dataProviderChanged ) {

removeAllChildren();

for each( var n : Number in this._dataProvider ) {

var l : Label = new Label();

l.text = n.toString();

addChild( l ); }

this._dataProviderChanged = false;

}

}

private function dataProviderChangeHandler( e : Event ) : void {

dataProviderChanged = true;

invalidateProperties();

} Result: commitProperties called only twice (once during initialization)

Page 28: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 28 |

measure()measure()

Sizing phase of validation Purpose: Component can calculate its

‘natural’/preferred/default size based on content and layout rules.

Implicitly invoked when component children change size. (Don’t call measure() on your children).

Measurement occurs from the bottom up. <mx:Application>

<mx:HBox> <mx:Button /></mx:HBox>

</mx:Application>

Don’t count on it: Framework optimizes away unnecessary calls to measure().

Construction

Configuration

Attachment

Initialization

Invalidation

Validation

Detachment

Garbage Collection

Initialization

(Born)

Updating(Life)

Destruction

(Death)

Page 29: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 29 |

Overriding measure()Overriding measure()

Used for dynamic layout containers (Vbox etc.)

Use getExplicitOrMeasuredWidth() for children which are UiComponents

Use width for non UiComponents

ALWAYS called during initialization

Call super.measure() first!

Set measuredHeight, measuredWidth for

the default values; measuredMinHeight

and measuredMinWidth for the minimum.

Construction

Configuration

Attachment

Initialization

Invalidation

Validation

Detachment

Garbage Collection

Initialization

(Born)

Updating(Life)

Destruction

(Death)

To get up and running fast, explicitly size your

component.

Page 30: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 30 |

measure() examplemeasure() example

override protected function measure( ):void

}

super.measure( );

measuredHeight = measuredMinHeight = currentIcon.height;

measuredWidth = measuredMinWidth = currentIcon.width + displayNameLabel.getExplicitOrMeasuredWidth( );

{

Construction

Configuration

Attachment

Initialization

Invalidation

Validation

Detachment

Garbage Collection

Initialization

(Born)

Updating(Life)

Destruction

(Death)

Page 31: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 31 |

updateDisplayList()updateDisplayList()

Layout and Drawing Phase of Invalidation Purpose: Lay out component contents and perform any

drawing

Layout and positioning occurs from the top down, given:

<mx:Application><mx:HBox> <mx:Button /></mx:HBox>

</mx:Application>

super() is optional - don’t call it if you’re overriding everything it does

Size and lay out children

If the child is a UIComponent, size it with setActualSize() and position it with move()

» If the child is not a UIComponent, set the x, y, width and height properties.

Good place to use Flash Player Drawing API

Construction

Configuration

Attachment

Initialization

Invalidation

Validation

Detachment

Garbage Collection

Initialization

(Born)

Updating(Life)

Destruction

(Death)

Page 32: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 32 |

updateDisplayList() exampleupdateDisplayList() example

override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void

{

super.updateDisplayList(unscaledWidth,unscaledHeight);

displayNameLabel.move(currentIcon.x + currentIcon.width,0);

displayNameLabel.setActualSize(unscaledWidth-currentIcon.width, unscaledHeight);

{

Construction

Configuration

Attachment

Initialization

Invalidation

Validation

Detachment

Garbage Collection

Initialization

(Born)

Updating(Life)

Destruction

(Death)

Page 33: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 33 |

Phase 3: Destruction Phase 3: Destruction

Destroying the component » Detachment: Remove the component from the

display list» Components do not get validated or drawn

when off the display list » Once off the display list:

• You can re-parent the component, and it will be brought back to life.

• Re-parenting is cheaper then re-instantiating a component

» Garbage Collection• No active references can be tough• Common culprits include event listeners,

dictionaries and timers.

Construction

Configuration

Attachment

Initialization

Invalidation

Validation

Detachment

Garbage Collection

Initialization

(Born)

Updating(Life)

Destruction

(Death)

Page 34: Building Components In Flex3

Copyright 2009 Tikal Knowledge, Ltd. | 34 |

In Conclusion…In Conclusion…

» Flash Player Elastic Racetrack: Learn it, love it, live it.

» Invalidation: All the cool kids are doing it.

» The best component lifecycle reference is right in front of you: Read Framework Code.

Resources

» Elastic Racetrack» Updated Elastic Racetrack» Building custom components (ppt, source, video)» Diving deep with Flex component lifecycle