Register

If this is your first visit, please click the Sign Up now button to begin the process of creating your account so you can begin posting on our forums! The Sign Up process will only take up about a minute of two of your time.

Page 1 of 2 1 2 LastLast
Results 1 to 10 of 13
  1. #1
    Senior Member Tomaszewski's Avatar
    Join Date
    Oct 2006
    Location
    Exton, PA
    Posts
    194
    Member #
    14132
    Hey guys, so here is my questions:

    but wait, ok... this is still not working and I'm not sure how to get it to work.

    I want to have 2 classes:

    1. XMLLoader to load the data and store the data in a variable
    2. XMLDistributor to take the loaded data from XMLLoader and distribute the information into an Array

    From that point, I would want a 3rd class which would have appropriate Getters so that when called, it would spit out the appropriate multi-dimensional array column and return it to what called it.

    What I'm unsure about is, how can I get the data from XMLLoader to XMLDistributor using the events from above... I understand the getters and setters part... the part that's killing me is making sure the data is loaded and THEN passing it... that's what I'm trying to figure out.

    I hope I'm explaining this clearely...

    **************************** CODE ************************************

    Code:
    // .fla
    
    var loadXML:XMLLoader = new XMLLoader();
    loadXML.loadXMLFromFile("mapInfo.xml");
    
    var dist:XMLDistributor = new XMLDistributor();
    Code:
    // XMLLoader.as
    
    package
    {
        import flash.events.Event;
        import flash.events.EventDispatcher;
        import flash.net.URLLoader;
        import flash.net.URLRequest;
        
        public class XMLLoader extends EventDispatcher
        {
            private var _xmlData:XML;
    		private var _xmlDataArray:Array;
            
            public function XMLLoader()
            {
                // temp space
            }
            		
    		public function get getXMLData():XML
    		{
    			return _xmlData;
    		}
            
            public function loadXMLFromFile(urlToLoad:String):void
            {
                var theLoader:URLLoader = new URLLoader;
                theLoader.addEventListener(Event.COMPLETE, onDataComplete, false, 0, true);
                theLoader.load(new URLRequest(urlToLoad));
            }
            
            private function onDataComplete(event:Event):void
            {
                this._xmlData = new XML(event.target.data);
                event.target.removeEventListener(Event.COMPLETE, onDataComplete);
                dispatchEvent(new Event("XML_READY"));
            }        
    		
        }
    }
    Code:
    // XMLDistributor.as
    
    package
    {	
    	public class XMLDistributor
    	{
    		private var _xmlLoader:XMLLoader;
    		private var _xmlDataArray:Array;
    		
    		public function XMLDistributor():void
    		{
    			_xmlLoader = new XMLLoader();
    			checkXMLLoader();
    		}
    		
    		private function checkXMLLoader():void
    		{
    			_xmlLoader.addEventListener("XML_READY", buildArray, false, 0, true);
    		}
    						
    		private function buildArray():void
            {
    
    		_xmlLoader.getXMLData;
    		trace(_xmlLoader.getXMLData);
    
    		}
    
    	}
    }
    note the custom Event handler in XMLLoader.as that is being called upon XMLDistributor.as being instantiated

  2.  

  3. #2
    Senior Member
    Join Date
    Jun 2005
    Location
    Atlanta, GA
    Posts
    4,146
    Member #
    10263
    Liked
    1 times
    Well, your problem is that the XMLLoader object that you're creating to load the data is different from the one being automatically instantiated in the XMLDistributor class. You have to pass the XMLLoader object in your first snippet into the XMLDistributor so that you can listen to the event coming from the object actually loading the XML. Events come from specific objects, so if you don't add the event listener on the same object that dispatches the event, you won't get it.

    As a side note, remember that in ActionScript 3 it is perfectly acceptable not to have explicit getters and to use public variables instead.

  4. #3
    Senior Member Tomaszewski's Avatar
    Join Date
    Oct 2006
    Location
    Exton, PA
    Posts
    194
    Member #
    14132
    Quote Originally Posted by Shadowfiend
    Well, your problem is that the XMLLoader object that you're creating to load the data is different from the one being automatically instantiated in the XMLDistributor class.
    I'm not following... how is it different? :ermm:

    Quote Originally Posted by Shadowfiend
    You have to pass the XMLLoader object in your first snippet into the XMLDistributor so that you can listen to the event coming from the object actually loading the XML.
    Yes, that's my question... how do I pass it to XMLDistributor, while having XMLDistributor wait for XMLLoader to load the XML fully?

    Quote Originally Posted by Shadowfiend
    Events come from specific objects, so if you don't add the event listener on the same object that dispatches the event, you won't get it.
    Can you explain what you mean by "the object that dispatches the event"?

    In my XMLLoader class, the onDataComplete method is pumping out dispatchEvent(new Event("XML_READY"));
    and I need XMLDistributor to wait for onDataComplete to finish before it starts to pull the XML data into an array.

    Quote Originally Posted by Shadowfiend
    As a side note, remember that in ActionScript 3 it is perfectly acceptable not to have explicit getters and to use public variables instead.
    This i did not know... however, I'd rather use the getters and setters just for compliance...

  5. #4
    Senior Member Tomaszewski's Avatar
    Join Date
    Oct 2006
    Location
    Exton, PA
    Posts
    194
    Member #
    14132
    ok i started thinking more about what you were saying and I got it to work. Thanks.

    This helped a lot the more I thought about it:

    Quote Originally Posted by Shadowfiend
    Events come from specific objects, so if you don't add the event listener on the same object that dispatches the event, you won't get it.
    Can you however answer the remaining questions from my last post? I"m interested by what you meant...

    -------------------------------------- SOLUTION -----------------------------------

    For anyone who's suffering the same problem, here is the code:

    intMap.fla
    Code:
    var loadXML:XMLDistributor = new XMLDistributor();
    loadXML.getXML("mapInfo.xml");
    XMLLoader.as Class
    Code:
    package
    {
        import flash.events.Event;
        import flash.events.EventDispatcher;
        import flash.net.URLLoader;
        import flash.net.URLRequest;
        
        public class XMLLoader extends EventDispatcher
        {
            public var _xmlData:XML;
            
            public function XMLLoader()
            {
                // temp space
            }
            
            public function loadXMLFromFile(urlToLoad:String):void
            {
                var theLoader:URLLoader = new URLLoader;
                theLoader.addEventListener(Event.COMPLETE, onDataComplete, false, 0, true);
                theLoader.load(new URLRequest(urlToLoad));
            }
            
            private function onDataComplete(event:Event):void
            {
                this._xmlData = new XML(event.target.data);
                event.target.removeEventListener(Event.COMPLETE, onDataComplete);
                dispatchEvent(new Event("XML_READY"));
            }        
    		
        }
    }
    XMLDistributor.as Class
    Code:
    package
    {
        import flash.events.Event;
        import flash.events.EventDispatcher;
    
    	public class XMLDistributor 
    	{
    		private var _xmlLoader:XMLLoader;
    		private var _xml:XML;
    
    		
    		public function XMLDistributor():void
    		{
    			_xmlLoader = new XMLLoader();
    			
    		}
    		
    		public function getXML(url:String):void
    		{
    			_xmlLoader.loadXMLFromFile(url);
    			_xmlLoader.addEventListener("XML_READY", onDataReady, false, 0, true);
    		}
    		
    		private function onDataReady(event:Event):void
    		{
    			trace(_xmlLoader._xmlData);
    		}
    	}
    }
    Explenation: XMLDistributor is instantiated and url is passed to method getXML(). XMLDistributor constructor instantiates XMLLoader class and function getXML() calls public function loadXMLFromFile() which opens the loader and tells it to wait until its done grabbing the XML file. It does this via the eventListner which calls onDataComplete(). onDataComplete() dispatches its own event "XML_READY" which method getXML() in XMLDistributor class takes and waits for the data to be complete. Once the XML data is complete, onDataReady() in XMLDIstributor class is called and it traces the public var _xmlData from XMLLoader class.

  6. #5
    Senior Member
    Join Date
    Jun 2005
    Location
    Atlanta, GA
    Posts
    4,146
    Member #
    10263
    Liked
    1 times
    Good explanation.

    Regarding your last question -- I'm assuming you mean about the public variables vs getters/setters. In the Java and C++ worlds, it is common to require getters and setters for any instance variables that need to be accessed externally. The point here is encapsulation -- making sure that everyone has to go through a method means that if the implementation ever changes, you can keep the public API the same while changing the internals of how it is operated.

    A good example of this is delaying instantiation. In C++ or Java, if I initially write a class that has a File as one of its instance variables, and I want to provide an outside entity access to that file, I would write a getFile() getter. Then, if I ever wanted to instantiate the file the first time it is accessed, instead of in my constructor, I could change the getFile() method to instantiate the file if needed. If I made the file instance variable public instead, then a user would say myObject.file. If I wanted to delay instantiation then, I would have to make the file variable private and then add a getter. But the user who was accessing myObject.file would have to change their code, because file is no longer accessible.

    In ActionScript 3, accessing a variable that is public uses exactly the same syntax as calling an instance variable's getter method. So if I did myObject.file for a public variable, and I then wanted to add instantiation, I would make the file variable private, rename it to _file, and then create a getter function [minicode]public function get file():File[/minicode]. The user, however, would continue to use it the same way -- myObject.file -- so nothing changed.

    For this reason, in AS3, there is no need to write the extra code for a getter/setter if they don't need to be doing anything other than get or set the variable. If you ever need to add behavior later, you only have to change the main class, not any of its consumers. In fact, I consider it sloppy coding to write unnecessary getters and setters, as it is unnecessary code sitting in your file that gets in the way of understanding what the code is doing.

    EDIT: As a side note, currently your new XMLDistributor class's getXML method adds the event listener after starting the loadXMLFromFile process. Though highly unlikely, there is the theoretical possibility that the loadXMLFromFile process will complete before the code adding the event listener is actually run. I would advise adding the listener before the loadXMLFromFile method is called.

    In fact, it would make the most sense to add the event listener in the constructor, where the XMLLoader is instantiated, since otherwise if you try to load multiple files with the same distributor, you will repeatedly try to add the same event listener. I'm not 100% sure how Flex's event listener interface works on the inside, so there are two possible outcomes -- either addEventListener will run a lookup every time you call it after the first time and see that the function has already been added, and then do nothing, or you will actually have your function added multiple times as an event listener, resulting in it being called multiple times when the event is dispatched. Neither of these are good, and adding it in the constructor ensures you only add it once.

  7. #6
    Senior Member Tomaszewski's Avatar
    Join Date
    Oct 2006
    Location
    Exton, PA
    Posts
    194
    Member #
    14132
    Quote Originally Posted by Shadowfiend
    Good explanation.

    Regarding your last question -- I'm assuming you mean about the public variables vs getters/setters. In the Java and C++ worlds, it is common to require getters and setters for any instance variables that need to be accessed externally. The point here is encapsulation -- making sure that everyone has to go through a method means that if the implementation ever changes, you can keep the public API the same while changing the internals of how it is operated.

    A good example of this is delaying instantiation. In C++ or Java, if I initially write a class that has a File as one of its instance variables, and I want to provide an outside entity access to that file, I would write a getFile() getter. Then, if I ever wanted to instantiate the file the first time it is accessed, instead of in my constructor, I could change the getFile() method to instantiate the file if needed. If I made the file instance variable public instead, then a user would say myObject.file. If I wanted to delay instantiation then, I would have to make the file variable private and then add a getter. But the user who was accessing myObject.file would have to change their code, because file is no longer accessible.

    In ActionScript 3, accessing a variable that is public uses exactly the same syntax as calling an instance variable's getter method. So if I did myObject.file for a public variable, and I then wanted to add instantiation, I would make the file variable private, rename it to _file, and then create a getter function [minicode]public function get file():File[/minicode]. The user, however, would continue to use it the same way -- myObject.file -- so nothing changed.

    For this reason, in AS3, there is no need to write the extra code for a getter/setter if they don't need to be doing anything other than get or set the variable. If you ever need to add behavior later, you only have to change the main class, not any of its consumers. In fact, I consider it sloppy coding to write unnecessary getters and setters, as it is unnecessary code sitting in your file that gets in the way of understanding what the code is doing.
    This makes perfect sense and a great explenation of it. I didn't realize the real use of the getter/setter. However, how would one delay instantiation??? Through the use of an event???

    Quote Originally Posted by Shadowfiend
    EDIT: As a side note, currently your new XMLDistributor class's getXML method adds the event listener after starting the loadXMLFromFile process. Though highly unlikely, there is the theoretical possibility that the loadXMLFromFile process will complete before the code adding the event listener is actually run. I would advise adding the listener before the loadXMLFromFile method is called.

    In fact, it would make the most sense to add the event listener in the constructor, where the XMLLoader is instantiated, since otherwise if you try to load multiple files with the same distributor, you will repeatedly try to add the same event listener. I'm not 100% sure how Flex's event listener interface works on the inside, so there are two possible outcomes -- either addEventListener will run a lookup every time you call it after the first time and see that the function has already been added, and then do nothing, or you will actually have your function added multiple times as an event listener, resulting in it being called multiple times when the event is dispatched. Neither of these are good, and adding it in the constructor ensures you only add it once.
    This also makes sense, however, in the interest of learning and not stopping on AS3, would it also be sloppy in the interest of getting used to using them, etc?

  8. #7
    Senior Member
    Join Date
    Jun 2005
    Location
    Atlanta, GA
    Posts
    4,146
    Member #
    10263
    Liked
    1 times
    The delayed instantiation I was talking about is something like this:

    Code:
    public class FileConsumer
    {
        public var filename:String;
        private var _file:File;
    
        public function FileConsumer(filename:String)
        {
            this.filename = filename; // Store the filename.
        }
    
        public function get file():File
        {
            if (_file == null)
                _file = new File(filename);
    
            return _file;
        }
    }
    There are a couple of things that set/get functions get you here. In this example, there is no set function, which effectively makes the file property read-only. In addition, the actual File object is only created the first time that it is requested. Otherwise, it does not exist.

    As for the interest of learning... I've always thought that in the interest of learning, one should get accustomed to best practices immediately rather than waiting for later. Otherwise you develop bad habits and before you know it you're developing professional products with those same bad habits. It's really up to you, however.

  9. #8
    Senior Member Tomaszewski's Avatar
    Join Date
    Oct 2006
    Location
    Exton, PA
    Posts
    194
    Member #
    14132
    Quote Originally Posted by Shadowfiend
    The delayed instantiation I was talking about is something like this:

    Code:
    public class FileConsumer
    {
        public var filename:String;
        private var _file:File;
    
        public function FileConsumer(filename:String)
        {
            this.filename = filename; // Store the filename.
        }
    
        public function get file():File
        {
            if (_file == null)
                _file = new File(filename);
    
            return _file;
        }
    }
    There are a couple of things that set/get functions get you here. In this example, there is no set function, which effectively makes the file property read-only. In addition, the actual File object is only created the first time that it is requested. Otherwise, it does not exist.

    As for the interest of learning... I've always thought that in the interest of learning, one should get accustomed to best practices immediately rather than waiting for later. Otherwise you develop bad habits and before you know it you're developing professional products with those same bad habits. It's really up to you, however.
    i see, so you mean delay it by not running it immediatly, just setting a getter method so that it can be called at a future time, right?

    Also, as far as the getters/setters go, I would personally like to use them, because i did some vb.net in school and we used them there. From AS3, I'd like to dive into ASP.NET and I know that ASP uses getters/setters. So in the long run, I can take out getters/setters out of AS3. Does this sound resonable :ichatermm ??

  10. #9
    Senior Member
    Join Date
    Jun 2005
    Location
    Atlanta, GA
    Posts
    4,146
    Member #
    10263
    Liked
    1 times
    I mean, ultimately your coding style is your choice and your choice alone (unless you work in a company). But it's important to segregate different languages in your mind. One language does things one way, and the other a different one, syntactically. More importantly, stylistically, the community of one language will develop completely different standards from that of another one. You need to be able to code in the language you're coding in, not code in one while using style from the other.

    As a side note, I seem to recall that C# properties, at least, operate similarly to AS3 ones in that changing between a public variable and a setter/getter combination is transparent to the consumer of the class.

  11. #10
    Senior Member Tomaszewski's Avatar
    Join Date
    Oct 2006
    Location
    Exton, PA
    Posts
    194
    Member #
    14132
    Quote Originally Posted by Shadowfiend
    I mean, ultimately your coding style is your choice and your choice alone (unless you work in a company). But it's important to segregate different languages in your mind. One language does things one way, and the other a different one, syntactically. More importantly, stylistically, the community of one language will develop completely different standards from that of another one. You need to be able to code in the language you're coding in, not code in one while using style from the other.
    ...that's the thing... where i work everyone is uptight about the way stuff is programmed. If I wouldn't use a getter/setter, it would be questioned. :-\

    Quote Originally Posted by Shadowfiend
    changing between a public variable and a setter/getter combination is transparent to the consumer of the class.
    .... not sure what it means to be transparent to the consumer class...


Page 1 of 2 1 2 LastLast

Remove Ads

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
All times are GMT -6. The time now is 08:48 PM.
Powered by vBulletin® Version 4.2.3
Copyright © 2019 vBulletin Solutions, Inc. All rights reserved.
vBulletin Skin By: PurevB.com