Building Components In Flex3

50 %
50 %
Information about Building Components In Flex3
Technology

Published on July 23, 2009

Author: tikalknowledge

Source: slideshare.net

Description

Building Components in Flex3 is the topic of July 2009's Flex group meeting @ tikalk

Creating Custom Components in Flex 3

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.

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.

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.

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.

Invalidation / Validation theory Flash player Rendering model

Flash 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

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

Flash player frames On one hand : Flex application consists on 2 frames On the other hand : enterFrame event is continuously fired ? Question ?

On one hand : Flex application consists on 2 frames

On the other hand : enterFrame event is continuously fired

Flash player frames ! Answer !

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

The Elastic Racetrack Images courtesy of Sean Christmann User Actions • Interact with any non- validation events from this frame (mouse movements, timers, ENTER_FRAME s 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

Deferred Validation Model Waiting for update request Update Requested Invalidation Validation Validation occurs right before Rendering Invalidation Validation

Halo Component Lifecycle – Broken Down 3 Phase Lifecycle Initialization (Birth) Construction Configuration Attachment Initialization Updating (Life) Component responds to changes by using the Invalidation/Validation Model - Interaction -> invalidation - > validation Destruction (Death) Out of sight, out of mind Detachment Garbage collection

3 Phase Lifecycle

Initialization (Birth)

Construction

Configuration

Attachment

Initialization

Updating (Life)

Component responds to changes by using the Invalidation/Validation Model - Interaction -> invalidation - > validation

Destruction (Death)

Out of sight, out of mind

Detachment

Garbage collection



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(); }

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();

}

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)

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



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=&quot;myLabel&quot;/> </mx:Canvas> Construction Configuration Attachment Initialization Invalidation Validation Detachment Garbage Collection Initialization (Born) Updating (Life) Destruction (Death) <mx:Application ...> ... <local:Sample text=&quot;value!&quot;/> </mx:Application> Output: Sample constructor Sample.text setter Adding Sample to display list (which creates myLabel)

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=&quot;myLabel&quot;/>

</mx:Canvas>

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! {

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

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

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

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 = &quot;&quot;; private var textChanged:boolean = false; public function set text(value:String):void } _text = value; //store textChanged = true; //mark invalidateProperties(); //invalidate invalidateSize(); invalidateDisplayList(); } override protected function commitProperties():void{ super.commitProperties(); if(textChanged) { myLabel.text = text; textChanged = false;} // don’t forget to unmark !!! { }

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

Good :

private var _text:String = &quot;&quot;;

private var textChanged:boolean = false;

public function set text(value:String):void

}

_text = value; //store

textChanged = true; //mark

invalidateProperties(); //invalidate

invalidateSize();

invalidateDisplayList();

}

override protected function commitProperties():void{

super.commitProperties();

if(textChanged)

{

myLabel.text = text;

textChanged = false;} // don’t forget to unmark !!!

{

}

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: CONSTRUCTOR this.addChild( a ); CREATECHILDREN } ]]> </mx:Script> </mx:Application> COMMITPROPERTIES MEASURE UPDATEDISPLAYLIST CREATIONCOMPLETE Moral of the story: don’t add components to the stage until you need them.

Attachment : Addition to the display list

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

Without attachment, component lifecycle will stall.

<mx:Application ...>

<mx:Script>

<![CDATA[

override protected function createChildren() : void

{

super.createChildren();

var a : A = new A(); Output: CONSTRUCTOR

this.addChild( a ); CREATECHILDREN

}

]]>

</mx:Script>

</mx:Application>

Lifecycle Phase 1: Initialization Initialization main steps ( not all of them ! full list ) preinitialize event is dispatched createChildren() is called Calling invalidation methods initialize event is dispatched First full validation pass occurs 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

Initialization

main steps ( not all of them ! full list )

preinitialize event is dispatched

createChildren() is called

Calling invalidation methods

initialize event is dispatched

First full validation pass occurs

creationComplete event is dispatched

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



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 = &quot;stop&quot;; 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

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 = &quot;stop&quot;;

stopButton.addEventListener(MouseEvent.CLICK,stopBtnClickHandler);

controlBar.addChild(stopButton);

{



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)

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!



Phase 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)

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.



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()

Invalidation/validation model is split into 3 phases:

Update component properties

Update sizing & measurement information

Update drawing and positioning

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)

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() )

Invalidation/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=&quot; Click me! &quot; click=&quot; onClick() &quot; /> <test:BadList id=&quot; theList &quot; dataProvider=&quot; { arr } &quot; /> //the list creates a label for each entity in the array </mx:VBox> </mx:Application>

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=&quot; Click me! &quot; click=&quot; onClick() &quot; />

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

</mx:VBox>

</mx:Application>

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

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

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)

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)

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)

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() .

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.

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.

measure() 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)

override protected function measure( ):void

}

super.measure( );

measuredHeight = measuredMinHeight = currentIcon.height;

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

{

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)

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

updateDisplayList() 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)

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);

{

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)

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.



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

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

Add a comment

Related presentations

Presentación que realice en el Evento Nacional de Gobierno Abierto, realizado los ...

In this presentation we will describe our experience developing with a highly dyna...

Presentation to the LITA Forum 7th November 2014 Albuquerque, NM

Un recorrido por los cambios que nos generará el wearabletech en el futuro

Um paralelo entre as novidades & mercado em Wearable Computing e Tecnologias Assis...

Microsoft finally joins the smartwatch and fitness tracker game by introducing the...

Related pages

Building_Components_In_Flex3_And_Flex4 - scribd.com

Building_Components_In_Flex3_And_Flex4 - Download as Powerpoint Presentation (.ppt), PDF File (.pdf), Text File (.txt) or view presentation slides online.
Read more

Adobe Flex 3 resources

Describes application development tasks, such as creating applications, using Flex components, ... Building and Deploying Adobe Flex 3 Applications.
Read more

Building Components | LinkedIn

View 8610 Building Components posts, presentations, experts, and more. Get the professional knowledge you need on LinkedIn.
Read more

Apache Flex®

Apache Flex® is completely open ... The focus of this article is building a simple map ... Apache FlexJS 0.50 This release includes some new components, ...
Read more

Building_Components_In_Flex3_And_Flex4_图文_百度文库

Building_Components_In_Flex3_And_Flex4_IT/计算机_专业资料。Building_Components_In_Flex3_And_Flex4. Flex Component Lifecycle: Halo and Spark Deepa ...
Read more

Building_Components_In_Flex3_And_Flex4_文库下载

提供Building_Components_In_Flex3_And_Flex4文档免费下载,摘要:Building_Components_In_Flex3_And_Flex4automatch();
Read more

Building_Components_In_Flex3_And_Beyond_图文_百度文库

Building_Components_In_Flex3_And_Beyond_IT/计算机_专业资料。Creating New Components in Flex 3 and Beyond Deepa Subramaniam Flex SDK http://www. ...
Read more

Free, open-source framework | Adobe Flex

Flex is a highly productive, open source application framework for building and maintaining expressive web applications that deploy consistently on all ...
Read more

Jeffry Houser's Blog: Building Components from MX to ...

Jeffry Houser's Blog: Building Components from MX to Mobile: 360|Flex Session Results. ... (and Flex3) way of building components with the Halo/MX lifecycle.
Read more