1 (edited by wokay.wokay.wokay.wokay 2010-03-27 20:13:33)

Topic: using addListener to broadcast menu clicks

I'm having a problem with receiving a broadcast message.

The code loads an XML page (an RSS feed) and parses the data to pull out what I want. Since the XML page takes awhile to load, the parsing happens in a function inside main "my_xml.onLoad = function(success)".

I'm trying to create a Menu object based on the parsed data inside this "onLoad" function. Once the menu is created, I add "this" as a listener so that I know when the menu is clicked.

Unfortunately this works when I'm outside the "onload" function, but when I create the Menu inside the "onLoad" function the listener apparently doesn't pick up when the menu is clicked.

Code is below with parsing portion taken out:

class Main
{
    private var parent:MovieClip;
    public var clMenu:Menu;
    
    function Main(mc:MovieClip)
    {
        this.parent = mc;
        var my_xml:XML = new XML();
        my_xml.ignoreWhite = true;
        UI.mainScreen(mc, 0xEEEEEE, "", 20);
        loadXML(my_xml,"sample.rss");
        my_xml.onLoad = function(success) {    
              var listings = my_xml.firstChild;
              var titles = new Array;
              for (var i = 1; i <= 5; i++) {
                     titles[i - 1] = listings.childNodes[i].childNodes[0].childNodes[0].nodeValue;
                    // PARSING HAPPENS HERE
              }
              this.clMenu = new Menu(mc, titles, UI.BLUE_2, UI.BLUE_3, UI.WHITE);
              this.clMenu.addListener(this);
        }
        
    }
    
    function loadXML(xml:XML,url:String)
    {
            xml.load(url);
    }
    
    
       function onMenuSelect(i:Number)
    {
        trace(i);
    }

Re: using addListener to broadcast menu clicks

The problem is one of scoping.

Inside the onLoad() handler, "this" is the XML Object "my_xml", not the instance of Main.

One way to work around this is something like:

..
Object(my_xml).__ target = this; // adds property to the XML object that points to the Main instance
..
..
this.__target.clMenu = new Menu(mc, titles, UI.BLUE_2, UI.BLUE_3, UI.WHITE);
..

A more elaborate way to manage this is with Delegate objects.

Re: using addListener to broadcast menu clicks

There's another way to solve the problem of accessing out-of-scope variables inside such handlers: declare all variables and functions as static in classes where you don't really need to instantiate more than one object. Typically you don't have multiple Objects of "Main"-class. If you declare everything static here, you can access them from everywhere as Main.xyz. Personally, I only use Objects where necessary - like e.g. for buttons that might occur multiple times on the screen.