Question:
What is an EventDispatcher class?
Answer: Every object can be
traced to DisplayObject and that class inherits from the EventDispatcher
class.
This is a base class that provides important event model functionality for
every object on display list. The EventDispatcher class implements the IEventDispatcher interface. This allows
us to create custom classes that cannot inherit from EventDispatcher or one of its
subclasses to implement the IEventDispatcher interface to gain access to its methods.
The addEventListener() method of this
class is used to register event listeners. Several other methods of the EventDispatcher class provide useful
information about the existence of event listeners. The hasEventListener() method returns true if an event
listener is found for that specific event type on a particular display list
object. The willTrigger() method checks for event listeners on a particular display
list object, but it also checks for listeners on all of that display list
object’s ancestors for all phases of the event flow. The method returns true if it finds one
Question:
How to define an inner event listener or closure function?
Answer:
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="initApp()">
<fx:Script> <![CDATA[
import mx.controls.Alert;
private function initApp():void {
b1.addEventListener("click",
function(e:Event):void {
Alert.show("The button was clicked.");
}
);
}
]]> </fx:Script>
<s:Button id='b1' label="Click Me"/></s:Application>
Function closures are created anytime a function is
executed apart from an object/class. They retain the scope in which they are
defined and this leads to unexpected results some times.
The function bar() gets the function myProduct() returned by the function foo(). Now for returned function the local variables are x=2 and y=4. But when that function is called it still has x=10 which means it retains the variable.
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="foo()">
<s:layout> <s:VerticalLayout/> </s:layout>
<fx:Script> <![CDATA[
[Bindable]
private var answer:String;
private function foo():Function {
var x:int = int(ti1.text);
function rectArea(y:int):int {
// function closure defined
return x * y;
}
return rectArea;
}
private function bar():void {
var x:int = 2;// ignored
var y:int = 4; // ignored
var myProduct:Function = foo();
answer = myProduct(int(ti2.text)); // function closure called } ]]> </fx:Script>
<mx:Form width="107">
<mx:FormItem label="X">
<mx:TextInput id="ti1" text="10" width="37" textAlign="right"/>
</mx:FormItem>
<mx:FormItem label="Y" width="71">
<mx:TextInput id="ti2" text="20" width="38" textAlign="right"/>
</mx:FormItem>
<mx:Label id="label1" text="{answer}" width="71" textAlign="right"/>
</mx:Form>
<s:Button id='b1' label="Compute Product" click="bar()"/> </s:Application>
The function bar() gets the function myProduct() returned by the function foo(). Now for returned function the local variables are x=2 and y=4. But when that function is called it still has x=10 which means it retains the variable.
If the listener we pass to addEventListener
() is a nested inner function, we should not pass true
for useWeakReference. The reason is for Flex inner function is an object
and can be freed by garbage collector. If the value of useWeakReference is true then there is a possibility that GC might free the function and
the function will not be called when the event is triggered.
Question:
How to create event handler classes?
Answer:
We
can create an external file and use its methods to handle events. This makes
MXML application more readable and maintainable.
Then we can use this method in MXML to handle all the events like:package {
import flash.events.Event;
import mx.controls.Alert;
public class MyEventHandler {
public function MyEventHandler() {
// Empty constructor.
}
public function handleAllEvents(event:Event):void {
Alert.show("Some event happened.");
}
}
}
private
var myListener:MyEventHandler = new MyEventHandler();
private
function createHandler():void
{
b1.addEventListener(MouseEvent.CLICK, myListener.handleAllEvents); }
But the best way is to declare method as
static so that we need not to instantiate the class.
Question:
When should we use Event metadata tag?
Answer:
We
use this metadata tag for the following purposes.
ActionScript
components – Above
the class definition, but with in the package definition, so that the events
are bound to the class and not a particular member of the class.
MXML
components – In the tag of a MXML file.
[Event(name="eventName", type="package.eventType")]
The following example identifies the
enableChange event as an event that an actionscript component can dispatch
tag of an MXML file:
The following example shows the [Event] metadata tag with in[Event(name="enableChange", type="myEvents.EnableChangeEvent")]
public class MyComponent extends TextArea
{
...
}
<?xml version="1.0"?>
<!-- events\myComponents\MyButton.mxml -->
<mx:Button xmlns:mx="http://www.adobe.com/2006/mxml"
click="dispatchEvent(new EnableChangeEvent('enableChanged'));">
<mx:Script>
<![CDATA[
import myEvents.EnableChangeEvent;
]]>
</mx:Script>
<mx:Metadata>
[Event(name="enableChanged", type="myEvents.EnableChangeEvent")]
</mx:Metadata>
</mx:Button>
Now this can be used in application as shown:
<?xml version="1.0"?>
<!-- events/MainEventApp.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:MyComp="myComponents.*" >
<mx:Script>
<![CDATA[
import myEvents.EnableChangeEvent;
public function enableChangedListener(eventObj:
EnableChangeEvent):void {
// Handle event.
}
]]>
</mx:Script>
<MyComp:MyButton enableChanged="myTA.text='got event';" />
<mx:TextArea id="myTA" />
</mx:Application>
Question: What does calling preventDefault() on an event do? How is this enforced?
Answer: When a user
types into a text field, the default behavior is that the character is
displayed in the text field. Because the TextEvent.TEXT_INPUT event's
default behavior can be canceled, we can use the preventDefault() method
to prevent the character from appearing. An example of a behavior that is not
cancelable is the default behavior associated with the Event.REMOVED event,
which is generated whenever Flash Player is about to remove a display object from
the display list.
We can use the Event.cancelable property to check whether we can
prevent the default behavior associated with a particular event. If the value
of Event.cancelable is true,
then preventDefault() can be
used to cancel the event; otherwise, preventDefault() has no
effect.
<mx:Script>
<![CDATA[
private function textArea_textInput(evt:TextEvent):void {
if (evt.text == "\n") {
evt.preventDefault();
}
}
]]>
</mx:Script>
<mx:TextArea id="textArea" verticalScrollPolicy="on" width="160"
height="120" textInput="textArea_textInput(event);">
<mx:text>The quick brown fox jumped over the lazy dog.</mx:text>
</mx:TextArea>
To determine whether an event currently being
dispatched has had its default behavior prevented, we can check the return
value of the Event class’s instance method isDefaultPrevented() within a listener registered for that event.
Question:
How can we stop the event propagation?
Answer: We can
stop traversal of display list during any phase, by calling any one of the two
methods: stopPropagation() and stopImmediatePropagation(). Both
methods prevent an Event object from continuing on its way thorough the event
flow. However there is a slight difference about whether the remaining event
listeners of the current node are allowed to execute. The stopPropagation() method prevents the Event object from moving on to
the next node, but only after any other event listeners on the current node are
allowed to execute. The stopImmediatePropagation()
method also prevents the Event objects from moving on to the next node, but it
does not allow any other event listeners on the current node to execute.
Question:
What is custom event? What is clone() method in Event class?
Answer:
A custom event must override clone() and toString()
method. The Event.clone() returns a cloned copy of the event by setting
type property and any other new property. We define this method to return an
event instance created with the new operator.
package myEvents
{
//events/myEvents/EnableChangeEvent.as
import flash.events.Event;
public class EnableChangeEvent extends Event
{
public static const ENABLE_CHANGED:String = "enableChanged";
public var isEnabled:Boolean;
public function EnableChangeEvent(type:String,
bubbles:Boolean = false,
cancellable:Boolean = false
isEnabled:Boolean=false) {
super(type,bubble,cancellable);
this.isEnabled = isEnabled;
}
// Override the inherited clone() method.
override public function clone():Event {
return new EnableChangeEvent(type, isEnabled);
}
//Every custom event class must override toString(). Note that
// “eventPhase” is an instance variable relating to the event
// flow.
override public function toString():String{
return formatToString(“EnableChangeEvent”,“bubbles”,
“cancellable”, “eventPhase”, “isEnabled”);
}
}
}
Now still the question is what exactly is the
advantage of clone()? Actually if we have a situation that after catching the
event in its registered listener, we want to dispatch this event again then a
new instance of this event wont be created else every re-dispatch will result
into a new instance.
Question:
Can we register a single event handler for multiple components? Can we have
multiple listeners for single event?
Answer:
Yes, we can register single event handler for
multiple components in MXML and AS.
We can also define multiple listeners for a single event.
Question: What is display list?
<mx:Button id="b1" label="Click Me" click="submitForm(event)"/>
<mx:Button id="b2" label="Click Me, Too" click="submitForm(event)"/>
public function createHandlers(e:Event):void {
b1.addEventListener(MouseEvent.CLICK, submitForm);
b2.addEventListener(MouseEvent.CLICK, submitForm);
}
We can also define multiple listeners for a single event.
<mx:Script><![CDATA[
[Bindable]
private var s:String = "";
private function submitForm(e:Event):void {
// Handle event here.
s += "The submitForm() method was called. ";
}
private function debugMessage(e:Event):void {
// Handle event here.
s += "The debugMessage() method was called. ";
}
]]></mx:Script>
<mx:Button id="b1" label="Do Both Actions"
click='submitForm(event); debugMessage(event);'
/>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="createHandlers(event)">
<mx:Script><![CDATA[
[Bindable]
private var s:String = "";
public function createHandlers(e:Event):void {
b1.addEventListener(MouseEvent.CLICK, submitForm);
b1.addEventListener(MouseEvent.CLICK, debugMessage);
}
private function submitForm(e:Event):void {
// Handle event here.
s += "The submitForm() method was called. ";
}
private function debugMessage(e:Event):void {
// Handle event here.
s += "The debugMessage() method was called. ";
}
]]></mx:Script>
<mx:Button id="b1" label="Do Both Actions"/>
<mx:Label id="l1" text="{s}"/>
<mx:Button id="b2" label="Reset" click="s='';"/>
</mx:Application>
Question: What is display list?
Answer:
All
visual objects (including Flex containers and controls) are subclasses of the DisplayObject class. They are in a tree
of visible objects and make up the application. The root of the tree is Stage; below it is SystemManager object and then the Application Object. Child containers and controls are leaf nodes of
the tree. That tree is known as display list. The term display list object and node
are used interchangeably.
Question:
If we want to write highly cohesive flex components then how can we pass any
parameter along with Event and we don’t want to use CustomEvent.
Answer:
We can use data property of Event class.
Question: What is the
difference between creationComplete and mx.Application.applicationComplete events?
Answer:
Actually when creationComplete is called stage object is null. Stage is not
available creationComplete() is called rather Stage is only available when
called with updateComplete() and applicationComplete(). The creation order is
different for containers and components because a container can be parent of
other components or containers.
So
the order in which the events are dispatched by the application are
preinitialize(), initialize(), creationComplete(), updateComplete() and
applicationComplete().
preinitialize() is dispatched
when the component has been attached to its parent container, but before the
component has been initialized, or any of its children have been created. In
most cases, this event is dispatched too early for an application to use to
configure a component.
initialize() is dispatched
when a component has finished its construction and its initialization
properties have been set. At this point, all of the component’s immediate
children have been created (they have at least dispatched their preinitialize()
event), but they have not been laid out. Exactly when initialize events are
dispatched depends on the container’s creation policy, as described later in
this section.
creationComplete() is dispatched
when the component, and all of its child components, and all of their children,
and so on have been created, laid out, and are visible.
updateComplete() is dispatched
every time the container or component characteristics are changed.
applicationComplete() dispatches
events after the Application has been initialized, processed by the
LayoutManager and added to the display list. This is the last event dispatched
during an application startup. It is later than the application’s
creationComplete() event, which gets dispatched before the preloader has been
removed and the application has been attached to the display list.
Another
solution for this is using the callLater() function.The callLater() function queues the operation to be executed at next render event.
3 comments:
Good for interview preparation! Keep it up man!
Very useful information. In my opinion, the only thing may not be correct is about call later() method as it don't
delay code execution until the user interface is updated.
The callLater() method queues an operation to be performed for the next screen refresh, rather than in the current update.
The callLater() method is most commonly used with the creationComplete event to ensure that a component has finished being created before Flex proceeds with a specified method call on that component.
@Anonymous you are right that it delays it for next render event.
Post a Comment