Apache – Flex Listening for Events Issue

apache-flex

I am rather new to flex and am trying to figure out how to listen for a custom event I have created. Let me give you a little background on my app first.

My directory structure is as follows.

  • assets
  • components
  • control
  • events
  • model
  • util

In the model class (which is bindable) I have an ArrayCollection which will get loaded with data via a web service call and a datagrid in a specific component will bind to that ArrayCollection and display the data. The web service is invoked via a button press which initiates the search through an event.


model/ApplicationModel.as

[Bindable]
public class ApplicationModel
{
    //put specific model components here
    public var data:ArrayCollection;


    //the one instance in this Singleton
    private static var _instance:ApplicationModel;

    public function ApplicationModel()
    {
        if (_instance != null) throw new Error("ApplicationModel already exists!");
    }

    public static function getInstance():ApplicationModel
    {
        if (_instance == null) _instance = new ApplicationModel();
        return _instance;
    }

}

components/SearchBox.mxml

<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml">

<mx:Script>
    <![CDATA[
        import com.homedepot.di.tp.SCVTools.events.*;

        private function doSearch():void
        {
            var query:String = searchTI.text;

            //only want to dispatch an event if there is something to query
            if (query) dispatchEvent(new CustomEvent(CustomEvent.UPDATE_START,query));
        }
    ]]>
</mx:Script>
    <mx:Label  text="Enter Search Term"/>
    <mx:TextInput id="searchTI" enter="doSearch()" />
    <mx:Button label="Search" click="doSearch()"/>
</mx:HBox>

This search functionality works fine and will return the data that I want. What I need to be able to know is when this web service call is done so the view component can update other aspects of the view accordingly (hide columns of datagrid based on the data returned as an example).

My Application.mxml file will wire up my controller to listen for the CustomEvent. The controller will then delegate the work to actually call the web service and get the data. The delegate will create an HTTPService object and get the data. It will also process results of the HTTPService. I am currently trying to dispatch a new event in the function that handles the result of the HTTPService call. This does not seem to be working and it makes sense since the event will never bubble to my view component.


snippet of control/DataUpdateDelegate.as

 public override function parse(event:ResultEvent):void
    {
        super.parse(event);

        try
        {
            Application.debug("DataUpdateDelegate:parse");
            var data:Object = event.result.records.record;

            model.data = data as ArrayCollection;

            dispatchEvent(new CustomEvent(CustomEevent.UPDATE_END) );
        }
        catch (error:Error)
        {
            handleError(error);
        }   

    }

I have tried to wire this UPDATE_END event up in the Application.mxml file but that does not seem to work either.

Does anyone have any suggestions on how my view to listen to this event that is not dispatched from a child component but rather from an ActionScript class that knows nothing about the view component?

Thanks,

Thomas

Best Answer

You could bind a specific function to the data property using BindingUtils when your ApplicationModel is first set in your view:

public function set model(applicationModelInstance:ApplicationModel):void
{
    _applcationModelInstance = applicationModelInstance;
    BindingUtils.bindSetter(dataRefreshed, _applicationModelInstance, "data");
}

protected function dataRefreshed(value:Object):void
{
    // do whatever you need to do here. 
    // value==applicationModelInstance.data
}

De-registering a binding like this to avoid memory leaks is a bit tricky, but since your ApplicationModel is a singleton you don't need to anyways.

Related Topic