7 Replies Latest reply on Feb 22, 2008 12:42 PM by adfsmit

    Events have me stumped

    Level 1
      I'm a flex noob and have been stuck on this one problem for hours and still haven't found a solution - any suggestions?

      My application includes a custom component (canvas container with 10 comboboxes). I populate each of the comboboxes with data I collect from my database using simple SQL queries (SELECT DISTINCT MIXES FROM MYTABLE, etc). The custom component isn't displayed at startup and isn't between the <mx:Application> ... </mx:Application> tags but I would like to populate the comboboxes at application startup so that they are ready for display later. Initially I thought that a simple creationComplete="initCombos()" call in my custom component mxml would do this but I found that this function is called 10 times for each of the comboboxes, which overwhelms the database. Setting a boolean flag to ensure that the initCombos function was only called once also didn't help - the flag is reset :(

      Is there an event that I can trigger when the custom component has been completely created i.e. after all the combos have been created?

      I tried applicationComplete in the application mxml but how do I reference a function in the custom component mxml. I can reference a public function in the application mxml from my custom components mxml using the Application.application.Function1 approach but not vice versa. I am hesitant to create a custom event and am eager to hear of possible solutions to this. TIA

      Andre
        • 1. Re: Events have me stumped
          Gregory Lafrance Level 6
          If your custom component is not between the <mx:Application> ... </mx:Application> tags, then how is it included in your application? Can you give a little more detail and possibly some simplified code, then I'm sure we can help you with this fairly quickly.
          • 2. Events have me stumped
            Level 1
            Here's some code - sorry I'm pasting as is but the "Attach Code" button isn't showing.

            This is my application mxml showing the initApp function called after the creationComplete event. It calls my custom component that is embedded within customWidget.


            <code>
            <mx:Application
            xmlns:mx=" http://www.adobe.com/2006/mxml"
            xmlns:awx=" http://www.arcwebservices.com/2007/awx"
            xmlns:widget="com.esri.aws.awx.widget.*"
            xmlns:custom="components.*"
            xmlns:local="*"
            xmlns:view="view.*"
            layout="absolute"
            horizontalAlign="center"
            verticalAlign="middle"
            pageTitle="TxFlex Database"
            creationComplete="initApp()">
            <mx:Script>
            <![CDATA[

            import mx.containers.VBox;
            import mx.controls.Alert;
            import com.esri.aws.awx.widget.WidgetPopupManager;
            import com.esri.aws.awx.map.layers.overlays.BubbleMarker;
            import components.*;


            private function initApp():void {
            WidgetPopupManager.openWidget(customWidget);
            }

            ]]>
            </mx:Script>

            <awx:DockWidgetContainer>
            <widget:MyWidget id="customWidget"/>
            <awx:BaseMapWidget/>
            <awx:FindWidget/>
            <awx:PanZoomWidget/>
            </awx:DockWidgetContainer>
            </mx:Application>

            </code>


            Here's the custom component trimmed down. The function I would like to run at startup is initArrays().

            <code>
            <mx:Canvas
            xmlns:mx=" http://www.adobe.com/2006/mxml"
            width="225"
            height="225">
            <mx:Script>
            <![CDATA[

            import mx.core.Application;
            import mx.collections.ArrayCollection;

            [Bindable]
            private var Database_dp:ArrayCollection;

            private var response:Responder;
            private var SQL:String;

            private function getDatabases(Database:Array):void {
            var DatabasesForComboBox:Array=new Array(Database.length);
            DatabasesForComboBox[0]={label:"ALL",data:"%"};
            for(var i:int=1;i<=Database.length;i++) {
            DatabasesForComboBox ={label:Database[i-1].ORIGINAL_DB,data:Database[i-1].ORIGINAL_DB};
            }
            Database_dp=new ArrayCollection(DatabasesForComboBox);
            }


            public function initArrays():void {
            response=new Responder(getDatabases,Application.application.onFault("DB Error"));
            SQL="SELECT DISTINCT ORIGINAL_DB FROM SEC_DEF;";
            Application.application.gateway.call("TxFlex.doSQL",response,SQL);
            response=new Responder(getFacilities,Application.application.onFault("FAC Error"));
            SQL="SELECT DISTINCT FACILITY_TYPE FROM SEC_DEF;";
            Application.application.gateway.call("TxFlex.doSQL",response,SQL);
            response=new Responder(getDistricts,Application.application.onFault("District Error"));
            SQL="SELECT DISTINCT DISTRICT FROM SEC_DEF;";
            Application.application.gateway.call("TxFlex.doSQL",response,SQL);
            response=new Responder(getCountys,Application.application.onFault("County Error"));
            SQL="SELECT DISTINCT COUNTY FROM SEC_DEF;";
            Application.application.gateway.call("TxFlex.doSQL",response,SQL);
            response=new Responder(getClimates,Application.application.onFault("Climate Error"));
            SQL="SELECT DISTINCT CLIMATE FROM SEC_DEF;";
            Application.application.gateway.call("TxFlex.doSQL",response,SQL);
            response=new Responder(getLayers,Application.application.onFault("Layer Error"));
            SQL="SELECT DISTINCT LAYER_TYPE FROM SEC_DEF;";
            Application.application.gateway.call("TxFlex.doSQL",response,SQL);
            }
            }

            ]]>
            </mx:Script>
            <mx:Label text="Database" width="70" fontWeight="bold" x="10" y="10"/>
            <mx:ComboBox dataProvider="{Database_dp}" id="cbDatabase" width="120" x="88" y="8" change="numberSections()"></mx:ComboBox>
            <mx:Label x="10" y="36" text="Facility" width="70" fontWeight="bold"/>
            <mx:ComboBox x="88" y="34" dataProvider="{Facility_dp}" id="cbFacility" width="120" change="numberSections()"></mx:ComboBox>
            <mx:Label x="10" y="62" text="District" width="70" fontWeight="bold"/>
            <mx:ComboBox x="88" y="60" dataProvider="{District_dp}" id="cbDistrict" width="120" change="reDistrict()"></mx:ComboBox>
            <mx:Label x="10" y="88" text="County" width="70" fontWeight="bold"/>
            <mx:ComboBox x="88" y="86" dataProvider="{County_dp}" id="cbCounty" width="120" change="numberSections()"></mx:ComboBox>
            <mx:Label x="10" y="114" text="Climate" width="70" fontWeight="bold"/>
            <mx:ComboBox x="88" y="112" dataProvider="{Climate_dp}" id="cbClimate" width="120" change="numberSections()"></mx:ComboBox>
            <mx:Label x="10" y="140" text="Layers" width="70" fontWeight="bold"/>
            <mx:ComboBox x="88" y="138" dataProvider="{Layer_dp}" id="cbLayer" width="120" change="numberSections()"></mx:ComboBox>
            <mx:Button label="Map Sections" width="120" id="btnUpdate" click="filterSections()" x="88" y="192" toolTip="Plot markers identifying the filtered sections on the map"/>
            <mx:Label x="10" y="166" text="Number of filtered sections" fontWeight="bold"/>
            <mx:Label x="173" y="166" text="..." width="35" textAlign="right" id="lblN" color="#ff0000"/>
            </mx:Canvas>

            </code>

            Here's my widget container that holds the custom component which is displayed using <custom:sectionFilter id="buttonBox"/>

            <code>
            <mx:VBox
            xmlns:mx=" http://www.adobe.com/2006/mxml"
            xmlns:widget="com.esri.aws.awx.widget.*"
            xmlns:custom="components.*"
            implements="com.esri.aws.awx.widget.IWidgetView">
            <mx:Script>
            <![CDATA[

            import com.esri.aws.awx.widget.WidgetStates;
            import com.esri.aws.awx.widget.IWidget;

            private var m_widgetContainer:IWidgetContainer;

            [Bindable]
            private var m_widget:MyWidget;

            public function get widget():IWidget {
            return m_widget;
            }

            public function set widget(value:IWidget):void {
            m_widget=value as MyWidget;
            }

            public function set widgetState(value:String):void {
            currentState=value;
            }

            public function get widgetState():String {
            return currentState;
            }

            public function get widgetContainer():IWidgetContainer {
            return m_widgetContainer;
            }

            public function set widgetContainer(container:IWidgetContainer):void {
            m_widgetContainer=container;
            }

            ]]>
            </mx:Script>

            <mx:states>
            <mx:State name="{WidgetStates.INFO}">
            <mx:RemoveChild target="{buttonBox}" />
            <mx:AddChild>
            <mx:Text width="214" text="Use this filter tool to narrow your search. Only markers for those sections that satisfy your filter criteria will be shown." />
            </mx:AddChild>
            </mx:State>
            <mx:State name="{WidgetStates.ICON}">
            <mx:RemoveChild target="{buttonBox}" />
            <mx:SetStyle target="{this}" name="paddingLeft" value="0" />
            <mx:SetStyle target="{this}" name="paddingTop" value="0" />
            <mx:AddChild>
            <widget:IconWidgetView toolTip="Filter Sections"
            widget="{m_widget}"
            upIcon="@Embed(source='/images/customUp.png')"
            downIcon="@Embed(source='/images/customDown.png')"
            overIcon="@Embed(source='/images/customOver.png')"
            disabledIcon="@Embed(source='/images/customDisabled.png')" />
            </mx:AddChild>
            </mx:State>
            </mx:states>
            <custom:sectionFilter id="buttonBox"/>
            </mx:VBox>

            </code>

            Hope this all makes sense.

            • 3. Re: Events have me stumped
              HooMaster
              Have you tried using creationPolicy="all" in your mx:Application tag?
              • 4. Re: Events have me stumped
                Level 1
                Yes - forgot to mention that I tried that. Debugging the application with a breakpoint on initArrays still shows that it is called multiple times - although not 10 x but 4 x for some reason with creationPolicy="all" in the application mxml. I've also tried creationPolicy="all" on my custom component and widget but get the same result.
                • 5. Re: Events have me stumped
                  Garyl Woolworth Level 1
                  Theres a couple of ways you could do this, I think the easiest way that would go along with what you already have started would be to make your 10 queries in the application itself and set them to 10 individual public array collections. Then when your components are made later down the road with Combobox's that need a dataProvider you can do <mx:ComboBox id="myCB" dataProvider="{parentApplication.myDP}"/>. Make sure the array collections are Bindable. Hope this helps.
                  • 6. Re: Events have me stumped
                    Level 1
                    Thanks - I figured as much and am revising my code accordingly - I'll report back on my progress l8r
                    • 7. Events have me stumped
                      Level 1
                      Thanks to all - I have a solution. To count the number of sections at the start of the application it was necessary to change the label to point to a Bindable Number (nn) as follows:

                      <mx:Label x="173" y="166" text="{Application.application.nn}" width="35" textAlign="right" id="lblN" color="#ff0000"/>

                      The database hits are greatly reduced though using Kaotic101's suggestion. Thanks again.