tags:

views:

363

answers:

2

I'm using MATE on an Adobe Flex project for MVC. On one of our pages, we have a dialog window that is presented to the user that displays them information that comes from RPC. The pages where this dialog pops up is unrelated to the data being displayed so this is a separate model. How do I create a MATE mapping file that will create the dialog window, make it visible to the user, and then inject in data from a model?

Thanks for reading.

A: 

Personally, I wouldn't use a model to inject the data into your pop-up window. Unless you're sure you're only going to have one instance of your popup window at a time, I would create a custom component for your popup that has properties you can bind the data to.

Otherwise, just create the component like normal with its own presentation model and use the PopUpManager to pop up your component.

If you truly want to do that, just pop up your component like this:

private function PopUpMyWindow():void
{
    popWindow = PopUpWindowCustomComponent(PopUpManager.createPopUp(Application.application as DisplayObject, PopUpWindowCustomComponent, true));
    popWindow.addEventListener("mouseDownOutside", ClosePopupHandler);
}

private function ClosePopupHandler(event:FlexMouseEvent):void
{
  PopUpManager.removePopUp(popWindow);
}

Of course, you would still have to dispatch and handle the appropriate events in your Main Map to send the data to the popup's model.

Here's a quick and dirty example for the model-less popup component:

<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
  showCloseButton="true" 
  title="MyPopup" 
  close="removeMe();">
  <mx:Script>
    <![CDATA[

      import mx.managers.PopUpManager;

      [Bindable]
      public var message:String;

      [Bindable]
      public var myData:ArrayCollection;

      private function removeMe():void 
      {
        PopUpManager.removePopUp(this);
      }

    ]]>
  </mx:Script>

    <mx:Canvas>
        <mx:Label x="10" y="10" text="{ message }" fontWeight="bold"/>

        <mx:DataGrid id="myDataGrid" x="10" y="61" width="400" height="255" dataProvider="{myData}"></mx:DataGrid>
    </mx:Canvas>
</mx:TitleWindow>

Let me know if you have any questions! :)

Jason Towne
+1  A: 

Seems like you found an approach, but if you are interested in another idea, there is a really good thread on the Mate forums about how to approach popups in Mate. It includes some example code and discusses the best practices involved and why certain choices are being made:

Converting app with popups to Mate << Mate Forums

If I understand you correctly, here is some code to do what you need (adapted from that thread). It injects the result of an RPC call into the view (keeping the map agnostic of how the view displays that data), and the view will create a popup whenever there is data, and remove the popup whenever there is no data. The thread has further explanation of most of this code.

EventMap:

<Injectors target="{PopupParentView}">
    <PropertyInjector destinationKey="rpcData" 
                      source="{FooManager}" sourceKey="rpcData" />
 </Injectors>

PopupParentView: ...

private var popup : UIComponent;

private var rpcData : Object;

private function onPreinitialize( event : Event ) : void {
    BindingUtils.bindSetter(rpcDataChanged, this, "rpcData");
}

private function rpcDataChanged( value : Object ) : void {
    invalidateProperties();
}

override protected function commitProperties( ) : void {
    // two mutually exclusive branches: either the property can be interpreted as "show the popup"
    // and the popup doesn't exist, or we shouldn't show the popup, but it does exist. all other
    if ( rpcData != null && popup == null ) {
        popup = PopUpManager.createPopUp(...);
    } else if ( rpcData == null && popup != null ) {
        // make sure to set the popup property to null
            PopUpManager.removePopUp(popup);
            popup = null;
    }
}
</Script>
...
Brian
+1 Not an answer, but a good starting point. Thanks!
davidemm
Yeah good point -- I pulled some code from the thread (adapted as I have used it before). Let me know if this helps.
Brian
Thanks for the help Brian! I created a bare ActionScript class that doesn't inherit from any visual components, it's only purpose is to handle the popUpManager as you described in your answer. If some one else takes this approach, make sure, in MATE, you catch the FlexEvent.INITIALIZE event and within the handler, use the MATE ObjectBuilder tag to instantiate an instance of the object you created since it won't be created automatically as part of the view.
davidemm
Good point.Another alternative (depending on how your view is structured) is to put this code on an existing view component. Say for example you have a header at the top, and all of the popups are little notifications that appear. This code could be on the Header.mxml file and it just defines how it handles changes to the notification data (in this case by showing a Popup).Just throwing it out there -- the strategy you mentioned seems clean as well.
Brian