From Flash to Flex: Understanding Flex Events

vents drive and breathe life into Flex applications, so understanding them is crucial to Flex development. In the latest article in the "From Flash to Flex" series, Kris Hadlock explains Flex events and how to incorporate them into object-oriented code.

Everything in Flex occurs based on an event. This means that simply clicking a button or key to moving the mouse or receiving a response from a web service provides developers with the ability to trigger a custom event in their Flex applications. That’s a lot of control, and since Flex is not based on the request/response model of a standard web app, the app contains the functionality to perform those custom events without ever leaving the web page. This is because events are client-based—in other words, separated from the request/response model of a web page and do not require the page to refresh with every user interaction.

On the Web a Flex app is completely loaded upfront, which allows the functionality within to respond faster than a standard web request model. This will initially cause the user to wait until the app is fully loaded, but will save time when it counts, which is during usage.

Not having to wait for a page refresh also prevents the user from having problems maintaining context because the screen reacts instantaneously. With these additional benefits you would expect some new issues to arise, but the capabilities of Flex are not limited in any way when comparing them with a standard web app.

In this article you will learn how to leverage the power of events by dispatching them in your own custom classes. The source code for this project can be downloaded here.

If you feel you need some background on Flex development before diving into events, take a look at the previous articles in the From Flash to Flex series.

Event Dispatching

Dispatching your own events starts by extending the UIComponent. In the last article of the Flash to Flex series, "Creating ActionScript Components for Flex," I explained how to create a Flex component by extending the UIComponent.

This article will pick up where that article left off by adding the additional functionality to dispatch your own custom events when a headline is selected. As a quick recap, the headline component that we built ran from XML, which defined a URL and display text for different headlines. When the app loaded, the component would cycle through each of the headlines for a predetermined interval that we passed to the constructor. Each headline would display at the top of the page waiting for someone to click it and visit the corresponding URL.

Since the UIComponent extends the EventDispatcher, all subclasses of the UIComponent have access to the dispatchEvent() method.

Relying on the href to link us to the URL of a headline works great, but if we wanted to add some additional functionality each time a headline is selected, such as logging what headlines were selected and at what time, this functionality would not allow it.

Therefore we will use events to inform a custom handler of the selection and then we will dispatch an event and delegate it to the appropriate class, which will log the data that we define.

First of all, we need to change the way that our headlines are constructed to trigger an event in the href (see Listing 1) instead of just linking to the URL as we did before (see Listing 2).

Listing 1: Triggering an event
this.headlines.push("<a href=’event:"+ _headlines[i].attribute("action") +"’>"+ _headlines[i].text() +"</a>");
Listing 2: Simply linking to the URL
this.headlines.push(’<a href="’+ _headlines[i].attribute("action") +’" target="_blank">’+ _headlines[i].text() +’</a>’);

If you have developed with Flash, the first thing that you’ll probably notice in Listing 1 is that we are not using asfunction any more; there is now a way to trigger an event from an href.

Now that we have our event in place we need to add a listener to the textfield that we are creating to display the headlines.

To do this I have added the event listener to the createTextField method from our previous headline class and modified it a bit to handle the text directly as a parameter rather than assigning it after the field has been created (see Listing 3).

Listing 3: Adding an event listener
private function cycle(index:Number):void
{
   if(this.currentTextField != null) removeChild(this.currentTextField);
   this.currentTextField = this.createTextField(0, 0, 200, 100, this.headlines[index]);

   if(index == (this.headlines.length-1)) index = 0;
   else index++;

   if(this.__cycleTimeout != 0) clearTimeout(this.__cycleTimeout);
   this.__cycleTimeout = setTimeout(cycle, (this.delay*1000), index);
}

private function createTextField(x:Number, y:Number, width:Number, height:Number, text:String):TextField
{
   var format:TextFormat = new TextFormat();
   format.font = "Arial";
   format.color = 0x333333;
   format.size = 21;
   format.underline = true;

   var txtField:TextField = new TextField();
   txtField.x = x; txtField.y = y;
   txtField.width = width; txtField.height = height;
   txtField.autoSize = "left";
   txtField.defaultTextFormat = format;
   txtField.htmlText = text;
   txtField.addEventListener(TextEvent.LINK, onHeadlineSelected);

   addChild(txtField);
   return txtField;
}

In the createTextField method we added the event listener after the field has been created and assigned the value of the headline. Let’s not forget to include the appropriate class (see Listing 4).

Listing 4: Importing the TextEvent
import flash.events.TextEvent;

Now that our event is being listened to, the next step is to handle it. We will need to create an onHeadlineSelected method to correspond to the event that we defined previously (see Listing 5).

Listing 5: Handling the event
private function onHeadlineSelected(e:TextEvent):void
{
   var u:URLRequest = new URLRequest(e.text);
   navigateToURL(u, "_blank");

   e.currentTarget.addEventListener("textlink", Logger.GetInstance().Log);

   var tev:TextEvent = new TextEvent("textlink", false, false);
   var date:Date = new Date();
   tev.text = date.toString() +"::"+ e.text;
   e.currentTarget.dispatchEvent(tev);
}

If you are transitioning from Flash you’ll notice that there is no longer a getURL method. Instead we need to create a new URLRequest from our URL and then use it in the navigateToURL method, which allows us to target the browser window just as getURL did.

The next line assigns an event listener to a method called Log in a new class called Logger, which we will create in a moment (see Listing 6).

You’ll also notice that we are providing the listener with a custom type called textlink, which will prevent any recursion issues when our other events are fired.

Once we have the listener in place we need to create a new event, which in this case is a TextEvent, set the values that we want to pass the new method and finally dispatch the event to whomever is listening.

Now that we are finally dispatching events, let’s take a look at how to handle them from other classes.vents drive and breathe life into Flex applications, so understanding them is crucial to Flex development. In the latest article in the "From Flash to Flex" series, Kris Hadlock explains Flex events and how to incorporate them into object-oriented code.

Event Dispatching

When creating a new class we need to determine where we will place it in our class structure. In this case the Logger class is a utility, so we will add it to a new package called util.

We only want one instance of the Logger class, so we will make it a Singleton to prevent multiple instances from being created.

Listing 6: Logging custom events
package com.studiosedition.util
{
   import flash.events.TextEvent;

   public class Logger
   {
     private static var INSTANCE:Logger;

     public static function GetInstance():Logger
     {
        if(Logger.INSTANCE == null)
        {
          Logger.INSTANCE = new Logger();
        }
        return Logger.INSTANCE;
      }

     public function Log(e:TextEvent):void
     {
        var logText:Array = e.text.split("::");
        var date:String = logText[0];
        var url:String = logText[1];
        // Log the date and url that were clicked
        e.currentTarget.removeEventListener("textlink", Log);
     }

   }
}

When the event is dispatched the Logger’s Log method will fire and receive any properties that were set on the event. Since we set the event text to the current date and URL that was selected we will receive those values as the text property of the event parameter.

We can simply split them by our delimiter and handle logging however we deem appropriate. Once we have completed logging the user selection we will remove the listener to prevent any recursion from future textLink events.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值