Sending and Loading Variables


The preceding technique is appropriate when you want to simply load blocks of text from static URLs. However, often an application requires a greater degree of variability. In such cases, you need to send and/or load variables either by themselves or in conjunction with loading text.

Although there are lots of ways to send and load variables, the following sections look specifically at sending and loading URL-encoded variables using HTTP requests and responses through a URLLoader object, building on what we discussed in the preceding section regarding loading text.

Note

The URL-encoded format serializes values into a string that uses Web-safe characters. Variables are grouped into name/value pairs, which consist of the name of the variable and the value delimited by an equal sign. For example, a=1 is a name/value pair for a variable called a with a value of 1. If there are multiple name/value pairs, they are delimited by ampersands. For example, a=1&b=2 represents two variables: a and b.


Sending Variables

Sending variables requires that the resource receiving the request is capable of receiving the variables. For example, you can send variables to a PHP or ColdFusion page, but you cannot meaningfully send variables to a text file.

When you want to send variables, you have two basic options: appending the query string to the URL in the URLRequest object or using a URLVariables object.

When you construct a URLRequest object, you can simply append a query string to the URL. The following example constructs a URLRequest object that points to a URL with a query string:

var request:URLRequest = new URLRequest("data.php?index=0");


Sending data using this first technique has the advantage of being relatively simple to implement when the query string is simple. However, there are two primary disadvantages:

  • Adding lots of variables with dynamic values to the query string makes the code more difficult to read.

  • You can send the data only using HTTP GET.

The second technique uses a flash.net.URLVariables object. The URLVariables constructor does not require any parameters. After you've constructed a URLVariables object, you can assign arbitrary properties and values to the instance. Each property corresponds to a variable you want to send.

var variables:URLVariables = new URLVariables(); variables.a = 1; variables.b = 2;


You can then assign the URLVariables object to the data property of the URLRequest object, like this:

var request:URLRequest = new URLRequest("data.php"); request.data = variables;


Regardless of which technique you use to assign the variables, you employ the load() method of a URLLoader object to send the request just as you would when loading text. The only difference occurs when you want to send the variables using POST rather than GET. URLRequest objects send all requests using GET by default. If you want to specify the method explicitly, you can use the method property and assign to it either the GET or the POST constant of the flash.net.URLRequestMethod class, like this:

request.method = URLRequestMethod.POST; loader.load(request);


The following revision to the LimerickData class presented earlier in this chapter uses a PHP script as the request URL, and it sends two variables:

[View full width]

package com.peachpit.aas3wdp.limerickreader.data { import flash.events.EventDispatcher; import flash.net.URLLoader; import flash.net.URLRequest; import flash.events.Event; import flash.net.URLVariables; import flash.net.URLRequestMethod; import flash.net.URLLoaderDataFormat; public class LimerickData extends EventDispatcher { private var _loader:URLLoader; private var _limerick:String; private var _ids:Array; public function get limerick():String { return _limerick; } public function LimerickData() { _loader = new URLLoader(); _loader.addEventListener(Event.COMPLETE, onData); _limerick = ""; _ids = [0, 1, 2, 3]; } public function next():void { var index:uint = uint(_ids[Math.floor(Math.random() * _ids.length)]); var variables:URLVariables = new URLVariables(); variables.limerickIndex = index; variables.html = 0; var request:URLRequest = new URLRequest("http://www.rightactionscript.com/ limerick/limerick.php"); request.method = URLRequestMethod.POST; request.data = variables; _loader.load(request); } private function onData(event:Event):void { _limerick = _loader.data; dispatchEvent(new Event(Event.CHANGE)); } } }


Now the LimerickData class is configured to send a request with variables to a PHP script. The result is the same as before when it was loading data from four text files, but now it is able to point to a single PHP script.

Loading Variables

Not only can you send variables, you can also load variables. Loading variables differs from loading text only in how you ask Flash Player to interpret the return value. By default, Flash Player treats the data property of the URLLoader object as plain text. However, if you set the URLLoader.dataFormat property, you can specify that you want Flash Player to automatically attempt to decode the return value as variables. When that occurs, the data property is a URLVariables object, and you can simply retrieve the variable values by using the variable names.

To set the dataFormat property, use the VARIABLES constant of the flash.net.URLLoaderDataFormat class, like this:

loader.dataFormat = URLLoaderDataFormat.VARIABLES;


In the preceding examples, we've had to assume that there were four limericks, and we had to hard-code the indices that would return the limericks. In this example, we'll first load variables from a PHP script to retrieve the valid indices. The PHP script returns a string in the following format: limerickIds=0,1,2,3. Next we'll revise the LimerickData class so that it loads the data and parses it into an array before loading any of the limericks. Because the model cannot load the limericks until it has first loaded the variables, that introduces a dilemma: Currently, the main class calls the next() method immediately. There is no guarantee that the limerick IDs will have loaded before the next() method is called, and that will result in an unhandled error with the current implementation (because the _ids will be null.) You have two basic options:

  • Require a change to the main class so that it doesn't call next() until the IDs have loaded. This option entails dispatching and listening for an additional event.

  • Change the implementation of next() so that it handles requests elegantly if the IDs haven't yet loaded.

We'll opt for the second option. The next() method will test that _ids is not null before trying to make a request to the server. We'll add a property that keeps track of whether or not the next() method has been called. If that property is true, then the code will automatically call next() when the IDs load. Here's the updated class:

package com.peachpit.aas3wdp.limerickreader.data {    import flash.events.EventDispatcher;    import flash.net.URLLoader;    import flash.net.URLRequest;    import flash.events.Event;    import flash.net.URLVariables;    import flash.net.URLRequestMethod;    import flash.net.URLLoaderDataFormat;        public class LimerickData extends EventDispatcher {       private var _loader:URLLoader;       private var _limerick:String;       private var _idsLoader:URLLoader;       private var _ids:Array;       private var _pendingNext:Boolean;       public function get limerick():String {          return _limerick;       }       public function LimerickData() {          _loader = new URLLoader();          _loader.addEventListener(Event.COMPLETE, onData);          _limerick = "";          _idsLoader = new URLLoader();          _idsLoader.addEventListener(Event.COMPLETE, setIds);          _idsLoader.load(new URLRequest("http://localhost/limerick/limerickIndex.php"));          _idsLoader.dataFormat = URLLoaderDataFormat.VARIABLES;       }          private function setIds(event:Event):void {          _ids = _idsLoader.data.limerickIds.split(",");          if(_pendingNext){             next();          }        }       public function next():void {          if(_ids != null) {             var variables:URLVariables = new URLVariables();             variables.limerickIndex = _ids[Math.floor(Math.random() * _ids.length)];             variables.html = 0;             var request:URLRequest = new URLRequest("http://localhost/limerick/                limerick.php");             request.method = URLRequestMethod.POST;             request.data = variables;             _loader.load(request);          }          else {             _pendingNext = true;          }        }        private function onData(event:Event):void {           _limerick = _loader.data;           dispatchEvent(new Event(Event.CHANGE));        }      }   }


Now the code loads limerick IDs from the PHP script first. After it loads the IDs, it can load limericks from the limerick PHP script just as it did previously. This configuration is much more flexible because it allows us to change the IDs of the limericks by changing the output of the limerickIndex.php script rather than having to recompile the SWF with new IDs.




Advanced ActionScript 3 with Design Patterns
Advanced ActionScript 3 with Design Patterns
ISBN: 0321426568
EAN: 2147483647
Year: 2004
Pages: 132

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