Using the Delegate Class to Control Scope with Listeners


If you start to use components with your own Flash movies and nest components within other Movie Clip symbols or your own custom components, you might come across problems with your listener object's scope. Scope refers to how paths within the listener method are evaluated. For example, when you have the following basic function, the scope for the variable named sName is local to the function, not the current timeline:

 var sName:String = "Goliath"; function onClick():Void {    var sName:String = "David";    trace("sName: "+ sName); } onClick(); 

If you add that code to your Flash movie and test it, the Output panel shows the value for the local variable named sName, not the sName value declared outside of the function:

 sName: David 

Similarly, the this scope can vary depending on how a function is called. If you add the following code to a Flash movie and test it, the Output panel displays the same value for this, inside and outside of the function:

 trace("outside of function, this = "+ this); function onClick():Void {    trace("inside of function, this = "+ this); } onClick(); 

For this code, the Output panel displays:

 outside of function, this = _level0 inside of function, this = _level0 

However, if you use the same function, onClick, as a listener of a component, the this scope will refer to the component instance, not the owner of the onClick function (_level0):

 var cbt:mx.controls.Button; trace("outside of function, this = "+ this); function onClick(oEvent:Object):Void {    trace("inside of function, this = "+ this); } cbt.addEventListener("click", onClick); 

If you tested the movie with this code and clicked the cbt instance, the Output panel displays:

 outside of function, this = _level0 inside of function, this = _level0.cbt 

Generally, you'll find that you want to keep the scope of your listener objects under control, and not necessarily executing within the scope of the component emitting the event. This issue becomes more of a necessity to address with larger application architectures, but if you know the problem upfront, you'll save yourself many headaches in future Flash development. Luckily, the solution is pretty simple. If you use the Delegate class, you can control the scope of any handler very easily, regardless of whether the handler is a listener or a data handler for an XML object. The implementation of the Delegate class involves just two lines of code. In the following code sample, the Delegate class is imported and used to re-scope the onClick() handler to the Main Timeline (that is, _level0) for the Button listener:

 import mx.utils.Delegate; var cbt:mx.controls.Button; trace("outside of function, this = "+ this); function onClick(oEvent:Object):Void {    trace("inside of function, this = "+ this); } cbt.addEventListener("click", Delegate.create(this, onClick)); 

Here, the Delegate.create() method is used to build a new listener object that controls the scope of the onClick() handler. The create() method takes two parameters: the scope reference you want to use, and the handler that will be called. For our code example, the scope reference is the current timeline (_level0) and the handler is onClick. If you tested the above code in a Flash movie that contained a Button instance named cbt on the Stage, the following text would be displayed in the Output panel when you click the instance:

 outside of function, this = _level0 inside of function, this = _level0 

Now, the scope is identical, inside and outside of the function. Let's practice using the Delegate class with the button_listener.fla file you built in the last section.

  1. Open the button_listener.fla file you created in the last section, or make a copy of the same file from the ch33 folder of this book's CD-ROM. Resave this file as button_listener_delegate.fla.

  2. Select frame 1 of the actions layer, and open the Actions panel (F9 or Option+F9). Replace the code with the following script:

     import mx.utils.Delegate; var cbt:mx.controls.Button; function onClick(oEvent:Object):Void {    trace("onClick >")    trace("\tthis = "+ this);    for(var i in oEvent){       trace("\t" + i + "= "+ oEvent[i]);    } }; cbt.addEventListener("click", Delegate.create(this, onClick)); 

    In this new code, you eliminate the need to create a new listener object — the Main Timeline (_level0) is the listener. The onClick() function is being delegated to handle the responsibility of the "click" event from the cbt instance.

  3. Save the document, and test it (Ctrl+Enter or z+Enter). When you click the cbt instance, the Output panel displays the following text. The this scope now refers back to the Main Timeline (_level0), not the component instance itself:

     onClick >    this = _level0    target = _level0.cbt    type = click 

Tip 

We often use the \t backslash pair in trace() statements to tab (or indent) messages within a function call.

On the CD-ROM 

You can find the completed file, button_listener_delegate.fla, in the ch33 folder of this book's CD-ROM.




Macromedia Flash 8 Bible
Macromedia Flash8 Bible
ISBN: 0471746762
EAN: 2147483647
Year: 2006
Pages: 395

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net