0

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.

nitin
  • 75
  • 1
  • 12

2 Answers2

1

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).

Community
  • 1
  • 1
RIAstar
  • 11,912
  • 20
  • 37
  • Note that, Adobe generated code and examples notwithstanting, it's not a great idea to have Views loading data or dispatching events about loading data. – Amy Blankenship Oct 16 '12 at 17:55
  • @AmyBlankenship I have no views loading data in this example and I agree with your opinion on that. But would you mind explaining why dispatching events about loading data is not a good idea? AFAIK that's exactly what all those fancy frameworks do under the hood. – RIAstar Oct 16 '12 at 22:35
  • 1
    If you're dispatching an event and it can be "heard" on the display list, then it is being dispatched from a View. Since you're dispatching an event without an object associated, it's being dispatched from 'this'. You're expecting it to be heard from the stage, so clearly it's a View. Frameworks dispatch events about data, but not on the display list. They'll usually use a dedicated EventDispatcher used just for that purpose. – Amy Blankenship Oct 16 '12 at 22:53
  • @AmyBlankenship Ah yes you're right of course. I tried to simplify my answer so much I made a mistake. If the event is dispatched on the stage, that would act as your dedicated EventDispatcher. – RIAstar Oct 16 '12 at 23:39
  • 1
    It could. By explicitly creating an eventBus variable and populating it with the stage, you leave your options open. – Amy Blankenship Oct 16 '12 at 23:42
  • @AmyBlankenship Correct. That is indeed the approach I usually take. – RIAstar Oct 16 '12 at 23:45
  • @RIAstar instead of dispatching the event like this FlexGlobals.topLevelApplication.stage.dispatchEvent( new EmployeeEvent(EmployeeEvent.LIST_LOADED, employees) ); we can extend the Eventdispatcher class and use dispatchevent() directly. This way we don't have to use stage for dispatching the event and also we can add event listener in the view itself like this.addEventListener(event,handler) to listen to the event. – nitin Oct 17 '12 at 07:07
  • @nitin Indeed. But the caveat is that you have to pass a reference to that EventDispatcher around throughout the application, whereas you have the stage available everywhere already. Note that using Amy's eventbus suggestion you'd have the option to choose your dispatcher: it could be the stage or it could be any other IEventDispatcher. – RIAstar Oct 17 '12 at 08:39
  • @ntin DisplayObject already extends EventDispatcher. But classes that are not Views do not dispatch on the display list, so you can only "hear" them if you are listening directly to them. IMO, this is all to the good, since you can choose what is listening and what is not. – Amy Blankenship Oct 18 '12 at 12:13
  • @RIAstar I got your point now. Since the data class can dispatch event by extending the EventDispatcher but it will not be bubbled. If it doesn't bubbles the view can't listen to the event. So we have to pass and instance of eventdispatcher to this class. Right? – nitin Oct 19 '12 at 08:19
0

Given the types of questions you've been asking, you really should be considering a Framework such as Robotlegs or Mate. They give you the tools to wire your application together without horrible hacks that will limit your flexibility or complicate maintenance long-term.

Check out my previous answer here for links to the same project done without a framework, with Mate, and with Robotlegs.

Community
  • 1
  • 1
Amy Blankenship
  • 6,485
  • 2
  • 22
  • 45
  • I have used cairngorm and mate to achieve the purpose, it is always better to use some framework. I just wanted to know how to do things without using framework. Thanks for the reply :) – nitin Oct 17 '12 at 07:12
  • That's a different question. See here for more info http://www.developria.com/2010/05/pass-the-eventdispatcher-pleas.html http://www.developria.com/2010/04/combining-the-timeline-with-oo.html – Amy Blankenship Oct 17 '12 at 14:32
  • Thanks Amy for the above links, they were awsome. I learnt a lot after reading them. – nitin Oct 18 '12 at 04:33