17 Replies Latest reply on Aug 25, 2011 7:39 AM by Amy Blankenship

    Event trouble - dispatching an event from the main app?

    Godico77 Level 1

      I am new to Flex and recently I am trying to use custom events. Currently I have a custom component that dispatches a custom event when the user clicks a button. That event is being caught and handled in the main app file. That is working fine.

       

      Part of this event handling consists of requesting data from a remote server. When the data is returned, I instantiate an object to store it. What I want to do is to pass this object back to the custom component via a custom event that would be dispatched from the main app. Is that possible at all?

       

      I am dispatching the custom event but it is not being caught in the custom component, even though I added a listener there via addEventListener (and I create the listening function too).

       

      The reason I want to use an event, and not data binding is because I want to be able to do some manipulation/formatting of the data in the object *within the custom component* BEFORE it gets displayed. I don't want to do this manipulation in the main app because it might have to be closely coupled with visual elements in the custom component, and I am trying to keep the business logic separated from the visual and the data (MVC model).

       

      Any ideas?

       

      Thanks in advance.

        • 1. Re: Event trouble - dispatching an event from the main app?
          Amy Blankenship Level 4

          Usually, we dispatch events from objects that do not know about the object receiving the event to other objects that do know about the dispatching even (for example, a child does not know about its parent, but a parent does know about the child, so the parent can add an event listener to the child and the child can dispatch an event without worrying if anyone is listening).

           

          For communications between an object and another object we're sure it knows about, we can use more direct means--for example, setting a property on a child object from a parent object.  If you absolutely must use an event for this, have the child listen to itself and dispatch the event on the child (myChild.dispatchEvent('foo')).

          • 2. Re: Event trouble - dispatching an event from the main app?
            Godico77 Level 1

            Thanks for your reply. I see what you mean, but in my case, the action that should trigger the event (the receiving of data from the remote server) is happening in the main application. So I don't see how I can fire the event from the child component since nothing is happening there to trigger this.

             

            What I am trying to implement is a simple search engine interface. The child component (a search form) triggers an event, when the user submits a search. That is handled in the main app (a request is sent to my remote server to get the data). When the data requested comes from the server, I save it into an object via code in a result handler function. But now I want to pass the saved object to the search form to be displayed, but I need to also format the data before displaying. I don't want to format the data in the main app because I am keeping the visual implementation details inside the child component. So what is the advisable thing to do here? Should I change the way I my application is organized?

             

            Thanks!

            • 3. Re: Event trouble - dispatching an event from the main app?
              Amy Blankenship Level 4

              I gave you code for how you'd fire an event in a child component from a parent component, so I'm not sure what's not to see.  However, my recommendation is that you take the other suggestion and set a property on the child component (such as dataProvider or something) from the parent, once the parent receives the data.

               

              It's extremely poor architectecture for a child component to have the faintest idea what its parent is doing, so I feel that the best avenue to help you is to help you avoid bad habits by telling you the right way to do what you're asking.

              • 4. Re: Event trouble - dispatching an event from the main app?
                Karl_Sigiscar_1971 Level 3

                You should have a data model, which you can implement as a Singleton with a getInstance() static method, that will make it accessible from anywhere in the application.

                 

                The other option is to have the data model injected, using an Inversion of Control (IoC) framework like Parsley.

                 

                Parsley will also offer you its powerful messaging system, which will allow you to dispatch an event from anywhere and get it handled anywhere in a fully decoupled way (dispatcher and receiver don't need to know about one another). While event bubbling forces you to have both the dispatcher and receiver objects to be both in the display list and in the same branch, Parsley messaging allows you to send and receive messages between objects that are not necessarily added to the stage, displayed or even visual. Also, it is more powerful than the classic non-bubbling target.dispatchEvent() where the dispatcher has to know what target is (which is coupling).

                • 5. Re: Event trouble - dispatching an event from the main app?
                  Godico77 Level 1

                  Sorry Amy, I totally misread your first reply - I didn't have my first cup of coffee yet...

                   

                  Now I REALLY see what you mean. It makes sense.

                   

                  Thanks for the help. I do want to try doing this the right way!

                  • 6. Re: Event trouble - dispatching an event from the main app?
                    Amy Blankenship Level 4

                    IMO, having a Singleton introduces far more coupling than even having a child component know about its parent component (http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/).  Obviously, a parent component already is coupled to its child component (while it's not impossible to add a child to a parent without the parent's explicit knowledge, it's seldom done), so you don't add any additional coupling by "talking" to a child from a parent, whether you're dispatching an event on the child or setting a property on it.

                     

                    IOC frameworks may be a bit much for someone who is new to Flex, but I'd suggest Mate or Robotlegs for a newer user, since both have a fair amount of guidance for new users to get up and running relatively quickly, whereas Parsley is pretty much wide open.  Note that having the parent inject the data model (set a property on the child with the correct information) is more straightforward, and probably where new users should start.

                     

                    -Amy

                    • 7. Re: Event trouble - dispatching an event from the main app?
                      Amy Blankenship Level 4

                      Just to clarify, there is nothing that prevents you from manipulating injected data before using it.

                       

                      For instance

                       

                      [Bindable]

                      protected var _stuff:String;

                       

                      protected var _myData:String;

                       

                      public function get myData():String {

                           return _myData;

                      }

                       

                      public function set myData(value:String):void {

                           if (value != _myData) {

                                _myData = value;

                                _stuff = _myData + ' something';

                           }

                      }

                       

                      Now you can bind to _stuff inside your component.

                       

                      HTH;

                       

                      Amy

                      • 8. Re: Event trouble - dispatching an event from the main app?
                        Karl_Sigiscar_1971 Level 3

                        Singletons are used throughout the Flex framework. Application.application or SystemManager are some examples.

                         

                        I personally prefer using injection when it comes to sharing data between views. I was using the ModelLocator pattern back in the days with Cairngorm 2. Probably easier for a new user to comprehend than IoC.

                        • 9. Re: Event trouble - dispatching an event from the main app?
                          Amy Blankenship Level 4

                          Yes, and this is unfortunate.  It makes the Flex framework more difficult to work with than it needs to be, and it is why the Flex Framework only has functional tests, not unit tests.

                          • 10. Re: Event trouble - dispatching an event from the main app?
                            Amy Blankenship Level 4

                            Plus, the things that were considered acceptable practice (event the GoF said they wished they'd never included Singleton in Design Patterns: Elements of Reusable Object-Oriented Software, so it was never truly considered "good" practice) in 2006 ish when the FW was written are not considered good practice now.  Even in the hey day of Cairngorm, many people were speaking out against its use of ModelLocator (http://blog.iconara.net/2008/04/13/architectural-atrocities-part-x-cairngorms-model-locato r-pattern/ ).

                             

                            Global access to a variable creates many truly horrible problems in a nontrivial software application, and once you start down that road, it's almost impossible to get out without a total rewrite of the system (I've been there!).  Telling a newbie to use Singleton is like telling a twelve-year-old to smoke.  One cigarette probably won't hurt them, but making a habit of it surely will.

                            • 11. Re: Event trouble - dispatching an event from the main app?
                              Karl_Sigiscar_1971 Level 3

                              Agreed. I don't smoke ;-)

                               

                              Farata Systems talks about a number of enterprise applications then rescued from Cairngorm 2...

                              • 12. Re: Event trouble - dispatching an event from the main app?
                                Karl_Sigiscar_1971 Level 3

                                Telling a newbie to use directly IoC is harsh. Even Martin Fowler didn't get it the first time he was told about it, as he recalls.

                                 

                                First, people learn Flex. Then they go on to learn an architectural framework.

                                 

                                When they are done with learning both, they can switch to designing and implementing large scale applications. While they are learning, they had better have a lead developer with them who knows Flex.

                                 

                                It all depends on where you are on the learning curve.

                                • 13. Re: Event trouble - dispatching an event from the main app?
                                  Amy Blankenship Level 4

                                  I disagree.  IoC (dependency injection) is simply providing a component with the dependencies it needs.  We ALL use dependencie injection, from the very first moment we program anything.  Even Math.abs(someNumber) is dependency injection--you are injecting someNumber into the abs function, so that it can calculate the absolute value.  myDatagrid.dataProvider = someArrayCollection is dependency injection.

                                   

                                  Now, it might be argued that telling some one to go straight to a DI framework is a bit of overkill, but DI itself is pretty simple. To the newbies on this thread, you can check out more info on the continuum between simple dependency injection and a DI framework here http://www.developria.com/2010/10/a-pragmatic-at-dependency-inje.html.

                                  • 14. Re: Event trouble - dispatching an event from the main app?
                                    Karl_Sigiscar_1971 Level 3

                                    I agree that Singletons can get very messy if you use them in large scale projects and especially if you think of them as a replacement to global variables. What Cairngorm 2 was doing is enforcing a structure for your application. It was far from perfect but still better than no structure at all.
                                       
                                    I use dependency injection together with MVC. Dependency injection alone is no warranty of having a good application structure. You need MVC for that. The other thing you need before you even get into design patterns is a good grasp of object oriented design.
                                       
                                    I have seen some very poorly designed Flex applications with dependency injection used everywhere to inject Presentation Models, but there was no MVC application structure to speak of, no central data model (data being scattered across all the PMs) and a lot of duplicated code (not due to dependency injection of course, but due to poor grasp of OOP).
                                       
                                    Also, I am concerned that, while people get obsessed with design patterns on the one hand, they don't get obsessed with the innards of the Flex framework, the way the underlyling Flash Player works or UI optimization techniques on the other. And that too can become critical when you create a large scale application.
                                           
                                    PS: As you know, Martin Fowler came up with the term dependency injection because he thought the term inversion of control was not simple to understand.

                                    • 15. Re: Event trouble - dispatching an event from the main app?
                                      Karl_Sigiscar_1971 Level 3

                                      And before anyone says that PMs rock. I know. I do use them. But I do have them bind to the central data model. My PMs filter or sort the central data.

                                      • 16. Re: Event trouble - dispatching an event from the main app?
                                        Amy Blankenship Level 4

                                        I'm actually not a big fan of a monolithic central data model.  Instead, I prefer to break information into the smallest pieces necessary to get the job done, and only letting a particular component have the one little piece it needs to accomplish its job.  I think this is one place Robotlegs excels--the injector is like a giant filing cabinet for these little pieces.  It encourages composition over inheritance.

                                         

                                        The project that you say had the data "scattered" everywhere, may indeed have used poor OOP, or it may have used OOP that was simply different enough from what you're used to that you found it difficult to work with.

                                         

                                        I agree that IoC is difficult to understand, particularly if you've always gone out of your way to embrace good practice and avoid Singletons/Statics.  The very term IoC assumes that having components reach out and get information from a global repository is the natural state.  As more people come along who have never experienced this state at all, much less as a natural state, it loses meaning.

                                         

                                        Interesting discussion, and probably more than the OP bargained for LOL.

                                        • 17. Re: Event trouble - dispatching an event from the main app?
                                          Karl_Sigiscar_1971 Level 3

                                          He sure got more than he expected ! ;-)

                                           

                                          A central data model doesn't have to be monolithic. It can be broken down into model objects that reflect those parts of your backend data model that are needed in the UI. Then PMs can act as views on the central data model, in addition to holding the view states and view logic.
                                             
                                          As stated in the documentation:
                                             
                                          An ICollectionView is a view onto a collection of data. The view can be modified to show the data sorted according to various criteria or reduced by filters without modifying the underlying data. An IViewCursor provides to access items within a collection. You can modify the collection by using the IViewCursor interface insert() and remove() methods.

                                           

                                          An ICollectionView may be a view onto data that has been retrieved from a remote location. When Implementing this interface for data that may be remote it is important to handle the case where data may not yet be available, which is indicated by the ItemPendingError.

                                           

                                          The IList interface is an alternative to the ICollectionView interface.

                                          ----------------------------------------------------

                                           

                                          When you inject by type, the IoC container injects Singletons, proving thereby that the Singleton pattern is not just a replacement for global variables.