apache-flexproperty-injection

How to pass data from one component to another component in flex


I have one class named as EmployeeResult where I am getting the response from the service. Inside the resulthandler I am getting an array of employees like name, id, age etc. I have one dataGrid inside the employeeView.mxml file. Inside the employeeView.mxml file I have an ArrayCollection which is the dataprovider to the datagrid. I want to update that arraycollection from inside the EmployeeResult file. When working with Cairngorm framework I have used the arraycollection inside the singleton to achieve the goal. In case of mate framework I have used the propertyinjector tags. But how do I achieve this objective in my case without any framework. How to achieve property injection without using ane framework or singleton class.


Solution

  • Continuing on your previous question: How to listen to events inside the child component dispatched by the parent component, you can simply dispatch a custom event containing that list of employees and notify the entire application of its arrival.

    Something like this:

    private function handleMyEmployeeResults(event:ResultEvent):void {
        var employees:IList = EmployeeResult(event.result).employeeList;
        dispatchEvent(new EmployeeEvent(EmployeeEvent.LIST_LOADED, employees, true));
    }
    

    Since this is a service result handler, we may assume that its class instance is not a view and hence it is not on the display list, which is why the event can't bubble. To address this we can dispatch the event directly on the stage.

    FlexGlobals.topLevelApplication.stage.dispatchEvent(
        new EmployeeEvent(EmployeeEvent.LIST_LOADED, employees)
    );
    

    Any view in your application can now listen for this event and set its properties accordingly:

    //inside View1
    stage.addEventListener(EmployeeEvent.LIST_LOADED, handleEmployeesLoaded);
    
    private function handleEmployeesLoaded(event:EmployeeEvent):void {
        myDataGrid.dataProvider = event.employees;
    }
    
    //inside View2
    stage.addEventListener(EmployeeEvent.LIST_LOADED, handleEmployeesLoaded);
    
    private function handleEmployeesLoaded(event:EmployeeEvent):void {
        myOtherKindOfList.dataProvider = event.employees;
        myFirstEmployeeLabel.text = 
            event.employees[0].firstname + event.employees[0].lastname;
    }
    

    Another more straightforward approach is to use your Application as a singleton. Create a bindable property employeeList on your main application. Now set its value when the results come in:

    private function handleMyEmployeeResults(event:ResultEvent):void {
        var employees:IList = EmployeeResult(event.result).employeeList;
        FlexGlobals.topLevelApplication.employeeList = employees;
    }
    

    Now you can bind to this property from anywhere in your application.

    <View1>
        <s:DataGrid dataProvider="{FlexGlobals.topLevelApplication.employeeList}" />
    </View1>
    
    <View2>
        <s:List dataProvider="{FlexGlobals.topLevelApplication.employeeList}" />
    </View2>
    

    Though this approach has the merit of being very easy to implement, it has all the downsides of a Singleton (e.g. poorly testable).