views:

52

answers:

3

How can I get some var / data from a custom classes?

The XML class

package classes
{
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.events.Event;
    import flash.display.MovieClip;

    public class videoData extends MovieClip
    {   
       private var myXML:XML;
       private var myXMList:XMLList;

       public function videoData()
       {
          var myXMLLoader:URLLoader = new URLLoader();
          myXMLLoader.load(new URLRequest("playlist.xml"));
          myXMLLoader.addEventListener(Event.COMPLETE, processXML);
       }

       private function processXML(e:Event):void
       {
          myXML = new XML(e.target.data);
          myXMList = new XMLList(myXML.children());
       }

       public function getXML()
       {
          return myXML;
       }
    }
}

The class that is calling the XML

package classes
{
    import flash.display.MovieClip;
    import flash.events.MouseEvent;
    import classes.videoData;

    public class playList extends MovieClip
    {
       private var vData:videoData = new videoData();

       public function playList()
       {
          trace(vData.getXML())
       }
    }
}
A: 

You are already getting your private myXML variable out through the .getXML() method. This is the best way to expose encapsulated data to outside classes.

An alternative would be to make your myXML field public instead of private, but using the get/set accessor methods you are hiding your actual implementation from outside world.

[Edit]

If your getXML() method is returning null, it means that your event handler (the processXML method) has not yet been called.

The problem appears to be in your VideoData constructor:

   public function videoData()
   {
      var myXMLLoader:URLLoader = new URLLoader();
      myXMLLoader.load(new URLRequest("playlist.xml"));
      myXMLLoader.addEventListener(Event.COMPLETE, processXML);
   }

The XML file is probably loaded before you attach the event handler, and that is why the event fires right before you start to listen to it. Try to reverse it and see if it works:

   public function videoData()
   {
      var myXMLLoader:URLLoader = new URLLoader();
      myXMLLoader.addEventListener(Event.COMPLETE, processXML); // moved up
      myXMLLoader.load(new URLRequest("playlist.xml"));
   }
Groo
but i can't get the myXML data, it only returns 'null'
Hwang
Did you try reversing these two lines?
Groo
yup, but it didn't work. Ain't you can't load something b4 you assign something for it to load?
Hwang
The `addEventListener` command attaches your custom handler method (`processXML`) to the "COMPLETE" event. If the `load` method loads the playlist immediately (before you attach your handler), it will have nobody to notify that something happened. In that case, you would attach your handler, but would never receive the event. Luckily, in this particular case, loading is a background async operation which usually takes more time to execute, so your handler gets attached in time.
Groo
A: 

You will need for the XML data to have been received before getting a value. Add a private Boolean _xmlLoaded in your videoData class , set it to true in the processXML method.

Create a getter

public function get xmlLoaded():Boolean
{
   return _xmlLoaded;
}

Now you can do this:

private var data:videoData = new videoData();
private var xmlData:XML;

private function init():void
{
   addEventListener(Event.ENTER_FRAME , xmlLoaded );
}

private function xmlLoaded(event:Event):void
{
   if( videoData.xmlLoaded )
   {
     xmlData = videoData.getXML();
     removeEventListener(Event.ENTER_FRAME , xmlLoaded );
   }
}
PatrickS
ugly solution... -1
OXMO456
@OXMO456 agreed , I would rather dispatch an event , but it seemed to bring another issue... you're right though , considering the OP mentioned OOP, best practice should be implied
PatrickS
+1  A: 

I would setup an event listener in 'playList' and dispatch an Event from 'videoData' once the XML has finished loading. That way you know when it's finished loading without using ENTER_FRAME (which will use alot more CPU as its checking every frame).

package classes
{
    import flash.events.*;
    import flash.display.MovieClip;
    import classes.VideoData;

    public class PlayList extends MovieClip
    {
       private var vData:VideoData;

       public function PlayList()
       {
           vData = new VideoData();
           vData.addEventListener(Event.COMPLETE, onXMLCompleteHandler);
       }

       private function onXMLCompleteHandler(e:Event):void
       {
           vData.removeEventListener(Event.COMPLETE, onXMLCompleteHandler);
           trace(vData.getXML());
       }
    }
}

package classes
{
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.events.Event;
    import flash.display.MovieClip;

    public class VideoData extends MovieClip
    {   
       private var myXML:XML;
       private var myXMList:XMLList;
       private var myXMLLoader:URLLoader;

       public function VideoData()
       {
          myXMLLoader = new URLLoader();
          myXMLLoader.load(new URLRequest("playlist.xml"));
          myXMLLoader.addEventListener(Event.COMPLETE, processXML);
       }

       private function processXML(e:Event):void
       {
           myXMLLoader.removeEventListener(Event.COMPLETE, processXML);
           myXML = new XML(e.target.data);
           myXMList = new XMLList(myXML.children());
           dispatchEvent(e);
       }

       public function getXML():XML
       {
           return myXML;
       }
    }
}

You should also ALWAYS capitalise your class names 'VideoData' not 'videoData'

lewi-p