2 Replies Latest reply on Jul 8, 2009 5:47 AM by kl1nt

    Where to plave groupingcollection.refresh() in Cairngorm design?

    sjerry-
      I wonder where to place the functionality to refresh a groupingcollection, in an advanceddatagrid, inside the Cairngorm framework?

      Situation:
      I have an advanceddatagrid with a groupingcollection for displaying product data. When the application is initialized, the getProductsEvent is dispatched. This will invoke the getProductsCommand wich will invoke getProductsDelegate. The delegate gets the data from the server and the command (wich implements the IResponder interface) will transform the data into an ArrayCollection and assign it to ShopModelLocator.getInstance().products.

      Problem:
      The problem is that the view (AdvancedDataGrid) is not updated after changed model.products. To do this, you have to invoke GroupingCollection.refresh().

      Question:
      The model doens't need to know the view. So invoke GroupingCollection.refresh() from the getProductsCommand is not an option. What is the best location to implement the logic that refreshes the groupingCollection? What is best practise?
        • 1. Re: Where to plave groupingcollection.refresh() in Cairngorm design?
          m_hartnett Level 3
          We struggled with this exact issue at the beginning of using Cairngorm as well and here are our solutions. I don't know if they are best practices since I could not find much info on the problem.


          Add a object capable of dispatching events in your model object.
          public var xmlDataLsnrO : ObjectProxy = new ObjectProxy(new Object());


          In any object that needs to be notified that a change to data has been made we added the code ( this code exists in our base class data grid so it is available to any object that extends the baseGrid)

          //this adds a new ArrayCollection to the listner object in the model.
          //The dataKey can be whatever you want to use. In your case it could possibly be "groupingData".
          if(model.xmlDataLsnrO[dataKey] == null)
          model.xmlDataLsnrO[dataKey] = new ArrayCollection();

          //The next lines add listeners to the object that contains the datagrid. It combines the dataKey with a set of standardized data event listener names. In the next lines we add three listeners. One for save, one for delete, and one for the initial load of the data. Each event has a coresponding listener method.

          var o1: ArrayCollection = model.xmlDataLsnrO[dataKey] as ArrayCollection;
          o1.addEventListener(dataKey + "SaveEvent",dataSavedHandler);
          o1.addEventListener(dataKey + "DeleteEvent",dataDeleteHandler);
          o1.addEventListener(dataKey + "LoadEvent",dataLoadHandler);

          In the command object we added the following code. Again this code is very generic because it has been taken from some base classes. We use the parmObj to maintain the requestKey which would be the same as the dataKey from the previous step
          //parmObj.requestKey would be equal to the dataKey defined in the previous step.
          //Get the arrayCollection out of the model listener object.
          var o1: ArrayCollection = model.xmlDataLsnrO[parmObj.requestKey] as ArrayCollection;

          //if the object exists then dispatch an event to any listener. Since your object that contains your datagrid object added itself to the arrayCollection then it will be notified of the data change. We have created a specific Event type for save, delete and load but you can use a plain old Event. Our save event actually passes the updated item to the method. Not really necessary
          if(o1 != null)
          o1.dispatchEvent(new DataSaveEvent(updatedItem as Object, parmObj.requestKey + "SaveEvent", "success"));

          In your datagrid object there is a method that get executed upon being notified. In this case it would be after a data save.

          protected function dataSavedHandler(dse : DataSaveEvent) : void {
          //do whatever you want to do here to refresh the grid.
          }


          That is about it. It give you the ability to add multiple object that want to be notified of changes to the arrayCollection. So if 3 screens need to be notified of changes to the groupingCollection you would just need to add them to the model listener arrayCollection for the key of groupingData.

          You need to remember to remove these listeners whenever the screen closes. This is very important so that memory will be cleaned up. Hope this is clear.
          • 2. Re: Where to plave groupingcollection.refresh() in Cairngorm design?
            kl1nt

            The simplest solution to a similar problem I had a while ago is the following:

             

                 - Change your model by extending EventDispatcher

                 - Dispatch an event from the result() method (should be a new event like, say, NotifyDoneEvent or sth similar).

                 - Listen for it in your application, and perform all operations there.

             

            This approach solves your problem, provided you make a new Event class and dispatch it. Your listener should also listen for the specific event string, not all events (because the model also dispatches a multitude of PropertyChange events).