Flash 8 introduced a new “feature” whereby EventDispatcher handles events named “load”, “draw”, and “move” differently. This broke the previous version of the XML2 class, which dispatches “load” events. I have updated it to use a “complete” event instead – it’s a little less intuitive perhaps, but it works. I’ve also added support for a “httpStatus” (F8 only) event, as well as adding some missing typing on method params.
For those unfamiliar with XML2, it is a simple extension of the built in XML class that provides:
- AS2 friendly EventDispatcher style event handling (addEventListener)
- Load timeout functionality
It’s API looks like so:
Constructor:
myXML2 = new XML2([xmlString:String]); |
-
xmlString
– optional parameter specifying an XML string to parse
Properties:
Inherits all properties from XML, and adds:
-
connectionTimeout
– specifies a maximum time in milliseconds to begin receiving XML data from the server. If no data is received within this period, a “complete” event will be fired with a success value of false, and the status property will be set to -101.
-
timeout
– specifies a maximum time in milliseconds to finish receiving all XML data from the server. If the load is not completed within this period, a “complete” event will be fired with a success value of false, and the status property will be set to -100.
Methods:
Inherits all methods from XML, and adds standard event dispatcher methods (addEventListener, removeEventListener).
Events:
XML2 removes the XML handlers (onLoad, onHTTPStatus) in favour of EventDispatcher events. The supported events are:
-
complete
– dispatched when the XML has been fully loaded and parsed, or an error occurs (ex. a timeout). Event object includes a boolean “success” property.
-
httpStatus
– (Flash Player 8 only) dispatched when the httpStatus is received (see XML.onHTTPStatus for details). Event object includes a numeric “httpStatus” property containing the status of the http request (ex. 404 – not found).
Here’s the XML2 example updated:
// import the class import com.gskinner.net.XML2; myXML = new XML2(); // subscribe to its load event: myXML.addEventListener("complete",this); // subscribe to its httpStatus event: myXML.addEventListener("httpStatus",this); // set the connection timeout period to 3 seconds (default is 7s): // (ie. data must begin loading within 3 seconds): myXML.connectionTimeout = 3000; // set the timeout period to 10 seconds // (ie. all data must be loaded within 10 seconds): myXML.timeout = 10000; // this should timeout after 3 seconds: myXML.load("http://1.1.1.1/nofile.xml"); // function to handle the complete event: function complete(p_evtObj:Object):Void { var XMLObj:XML2 = p_evtObj.target; trace("success: "+p_evtObj.success); trace("status: "+XMLObj.status); trace("toString: "+XMLObj.toString()); } // function to handle the httpStatus event: function httpStatus(p_evtObj:Object):Void { trace("http status: "+p_evtObj.httpStatus); } |
You can download XML2 by clicking here.
Hi Grant,
Why do you use setIntervall function to call the timeOut instead of setTimeOut() (which was not documented but available in Flash 8 API) ?
Greets,
++
hi grant.
quick questions.
1 – don’t seem to see where you are overridding the on HTTPStatus. am i reading things incorrectly?
2 – why not place the ‘this.onLoad = onXMLLoad’ in the constructor instead of in both of the ‘load’ and ‘sendAndLoad’ methods
3 – why do you do ‘delete(this.onLoad)’ in the ‘cancelLoad’ method?
4 – last one. this is also backward compatible with v7 players correct? thus the reason for not using setTimeOut() — see post above.
it’s all very nice stuff, and although i missed your first day presentation at spark, i heard that it was great!
thx
Thanks for putting this together, its basically a robust version of something I had planned on the back shelf.
I’m using it for a project that uses SendAndLoad and found it to cause some problems with my existing code, so I manipulated your code a bit to mask the Load part of SendAndLoad, thought you may be interested.
public function sendAndLoad(p_url:String):Void {
//setTimeouts()
this.onLoad = null;
var tmp = new XML2()
tmp.ignoreWhite = this.ignoreWhite
tmp.connectionTimeout = connectionTimeout
tmp.timeout = timeout
tmp.onLoad = onXMLLoad;
tmp.addEventListener(“complete”, Delegate.create(this, relayEvent))
tmp.setTimeouts()
super.sendAndLoad(p_url, tmp);
}
private function relayEvent(eObj:Object){
clearTimeouts();
dispatchEvent(eObj);
}
tmp doesnt get garbage collected till after the event is called, and you can recieve the xml2 object loaded via sendAndLoad through the same ‘complete’ listener you you use for xml.load. All that and the load part of SendAndLoad gets all the functionality of the xml2 object.
Hi Grant,
sendAndLoad, didn’t work out for me either.
Ian Turgeon (thanks!) made a good suggestion, but what i really would like is that you could give it a second param receiver:XML2 on which you could define the handlers then. It would work more like the traditionla one.
thanks!
Arnoud
I wonder (I’m a novice) about cleanup of eventListeners, wouldn’t (if used extensively in an application) just cause a buildup and cause a small memory leak? Can anyone give an example of proper cleanup for using this class?
Thanks,
Ryan
i cannot get your provided example working :/ flash throws an error about Boolean, String and other classes that they cannot be loaded :/
I like this class very much, because I always hated this callback-object-hack. I was looking for a way where you can simply pass the XML-URL to a class and get back the corresponding XML-Object. BUT, there is one issue that nearly drove me, itâs that you’re running in trouble when attaching Movieclips that are using this functionality.
If you register the onload event as a callback-function in a MC like that, the onload function is triggered twice, first when the object is initiated and twice when this XML2 class returns its result. So, to get rid of this, you have to reactivate your prototyping knowledge and write your onload function like this:
class LoaderClass extends MovieClip {
public function LoaderClass (){
var myXML:XML2 = new XML2();
myXML.addEventListener( “onLoad”, this );
myXML.load( _global.XML_URL );
}
public function onLoad(){
LoaderClass.prototype.onLoad = function( p_evtObj:Object ){
// your XML processing code here
}
}
}
Itâs just a quick and dirty solution I found, I can imagine there are way cooler solutions without prototyping but I had no time to explore the eventdispatcher and XML class in deep. If someone manages to find another way to do this, please drop me a note.
Cheers and thanks for your work
CU neutronenstern
neutronenstern:
The XML2 class does not dispatch an “onload” event. Instead it uses a “load” event, and in the version updated for flash 8, a “complete” event. This does not interfere with the built-in onload method.
Further, if it *did*, instead of using prototype hacks, you could simply use a Delegate (or the gskinner.com EventProxy class found here: http://www.gskinner.com/blog/archives/000091.html)