Select to view content in your preferred language

Global Variables

4865
3
Jump to solution
05-28-2012 05:06 AM
HelioHiroshi
Deactivated User
I'm trying to pass a variable generated dynamically in a widget to another widget(that can be opened or not). I tried to use singleton design pattern to try to achieve this, but it didn't seem to work, the variable never hold the value. I don't know if there's some standard way in flex viewer to create a global variable. Ideas are welcome.
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
IvanBespalov
Frequent Contributor
Using Singleton class TransferDataManager.as:
package ee {  import flash.events.Event;  import flash.events.EventDispatcher;   [Event(name="onDataChanged", type="flash.events.Event")]  [Bindable]  public class TransferDataManager extends EventDispatcher  {   public static const TRANSFER_DATA_CHANGED:String = "onDataChanged";      private static var _instance:TransferDataManager;      /**    * @private    */   public function TransferDataManager(caller:Function = null)    {     if (caller != hidden)     throw new Error ("TransferDataManager is a singleton class, use getInstance() instead");        if (_instance != null)     throw new Error("Only one Singleton instance should be instantiated");   }      /**    * @return instance of ResourcesManager    *     */   public static function getInstance():TransferDataManager   {    if(!_instance)    {     _instance = new TransferDataManager(hidden);    }    return _instance;   }      /**    * @private    */   private static function hidden():void {}      public var transferedData:Object = null;      public function updateTransferData(obj:Object = null):void   {    transferedData = obj;    dispatchEvent(new Event(TRANSFER_DATA_CHANGED));   }  } }

define it firstly in top level component ViewerContainer.mxml:
<!---     Main application container. --> <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"          xmlns:s="library://ns.adobe.com/flex/spark"          width="100%" height="100%"  preinitialize="group1_preinitializeHandler(event)" ... protected function group1_preinitializeHandler(event:FlexEvent):void    {     initDataManager();    }        [Bindable]    private var transferManager:TransferDataManager;        protected function initDataManager():void    {     trace("ViewerContainer::initDataManager()");     transferManager = TransferDataManager.getInstance();    }

Create SenderWidget.mxml:
<?xml version="1.0" encoding="utf-8"?> <viewer:BaseWidget xmlns:fx="http://ns.adobe.com/mxml/2009"                    xmlns:s="library://ns.adobe.com/flex/spark"                    xmlns:mx="library://ns.adobe.com/flex/mx"                    xmlns:viewer="com.esri.viewer.*"        preinitialize="basewidget1_preinitializeHandler(event)">     <fx:Script>         <![CDATA[    import ee.TransferDataManager;           import mx.events.FlexEvent;        [Bindable]    private var transferManager:TransferDataManager;     protected function button1_clickHandler(event:MouseEvent):void    {     trace("SenderWidget::button1_clickHandler()");     // create some data you wand to pass     var transferData:Object = new Object();     transferData.message = txtInput.text;     transferData.date = new Date();          // get transfer manager instance     transferManager = TransferDataManager.getInstance();     transferManager.updateTransferData(transferData);       }        protected function basewidget1_preinitializeHandler(event:FlexEvent):void    {     initDataManager();    }        protected function initDataManager():void    {     trace("SenderWidget::initDataManager()");     transferManager = TransferDataManager.getInstance();     transferManager.addEventListener(TransferDataManager.TRANSFER_DATA_CHANGED, onTransferDataChanged);    }        protected function onTransferDataChanged(event:Event):void    {     trace("SenderWidget::onTransferDataChanged()");    }          ]]>     </fx:Script>     <viewer:WidgetTemplate id="senderWidget"                            width="300" height="300">         <viewer:layout>             <s:VerticalLayout horizontalAlign="center" verticalAlign="middle"/>         </viewer:layout>          <s:TextInput id="txtInput" />   <s:Button label="Send" click="button1_clickHandler(event)" />     </viewer:WidgetTemplate> </viewer:BaseWidget>

and RecieverWidget.mxml:
<?xml version="1.0" encoding="utf-8"?> <viewer:BaseWidget xmlns:fx="http://ns.adobe.com/mxml/2009"                    xmlns:s="library://ns.adobe.com/flex/spark"                    xmlns:mx="library://ns.adobe.com/flex/mx"                    xmlns:viewer="com.esri.viewer.*"        preinitialize="basewidget1_preinitializeHandler(event)">     <fx:Script>         <![CDATA[    import ee.TransferDataManager;        import mx.events.FlexEvent;    import mx.utils.StringUtil;        [Bindable]    private var transferManager:TransferDataManager;     protected function basewidget1_preinitializeHandler(event:FlexEvent):void    {     trace("RecieverWidget::basewidget1_preinitializeHandler()");     initDataManager();    }        protected function initDataManager():void    {     trace("RecieverWidget::initDataManager()");     transferManager = TransferDataManager.getInstance();     transferManager.addEventListener(TransferDataManager.TRANSFER_DATA_CHANGED, onTransferDataChanged);     var transferedData:Object = transferManager.transferedData;          if (transferedData)     {      if (transferedData.hasOwnProperty("message") && transferedData.hasOwnProperty("date"))      {       var msg:String = StringUtil.substitute("{0} -> {1}", transferedData.message, transferedData.date);       writeLog(msg);      }     }    }        protected function onTransferDataChanged(event:Event):void    {     trace("RecieverWidget::onTransferDataChanged()");     transferManager = TransferDataManager.getInstance();     var transferedData:Object = transferManager.transferedData;          if (transferedData)     {      if (transferedData.hasOwnProperty("message") && transferedData.hasOwnProperty("date"))      {       var msg:String = StringUtil.substitute("{0} -> {1}", transferedData.message, transferedData.date);       writeLog(msg);      }     }    }        private function writeLog(message:String):void    {     trace("RecieverWidget::writeLog()");     log.text = StringUtil.substitute("{0}\n{1}", message, log.text);    }          ]]>     </fx:Script>     <viewer:WidgetTemplate id="recieverWidget"                            width="300" height="300">         <viewer:layout>             <s:VerticalLayout horizontalAlign="center" verticalAlign="middle"/>         </viewer:layout>      <s:TextArea width="100%" height="100%" id="log" />     </viewer:WidgetTemplate> </viewer:BaseWidget>


Sender and Receiver - is conditional. It can work in reverse mode.

View solution in original post

0 Kudos
3 Replies
IvanBespalov
Frequent Contributor
Creating Singleton class is not hard in Flex (a lot of samples in web) (EventBus.as in FlexVewer).

Other way - extend flex viewer widget management.

classes changed/extended (for Flex Viewer v2.5):
IBaseWidget.as
BaseWidget.as
WidgetManager.mxml
HeaderControllerWidget.mxml

extended methods:
/*IBaseWidget.as*/
 
 /* custom attributes */
 function set widgetAttributes(value:Object):void;
 function get widgetAttributes():Object;

***********----------------------------------*******************

/*BaseWidget.as*/

        [Bindable]
        private var _widgetAttributes:Object;

        //----------------------------------
 //  widget attributes
 //----------------------------------
 
 public function get widgetAttributes():Object
 {
  return _widgetAttributes;
 }
 
 /**
  * Set widget additional attributes.
  *
  * @param value the object.
  */
 public function set widgetAttributes(value:Object):void
 {
  _widgetAttributes = value;
 }

/*WidgetManager.mxml*/

 private function runWidget(attributes:Object):void
        {
  var widgetId:Number = attributes.id as Number;
                var widget:IBaseWidget = createWidget(widgetId);
  widget.widgetAttributes = attributes;
                openWidget(widget);
        }

 private function onRunWidget(event:AppEvent):void
 {
  var attributes:Object = event.data as Object;
                var id:Number = attributes.id as Number;
                var idx:Object = configData.widgetIndex[id];

                var wgtContainer:IWidgetContainer = configData.widgetContainers[idx.container].container.obj;
                var wgt:Object = configData.widgetContainers[idx.container].widgets[idx.widget];

                if (!widgetAdded)
                {
                    widgetAdded = true;
                }

                //widget loaded
                var widget:IBaseWidget;
                if (widgetTable.containsKey(id))
                {
                     widget = widgetTable.find(id) as IBaseWidget;
   widget.widgetAttributes = attributes;
                     //add back the container if exists
                     widget.setState(WidgetStates.WIDGET_OPENED);
                     wgtContainer.addWidget(widget);
                }
                else
                {
                     //module loaded
                     if (moduleTable.containsKey(wgt.url))
                     {
                         runWidget(attributes);
                     }
                     else
                     {
                         loadWidget(attributes);
                     }
                }
        }

 private function loadWidget(attributes:Object):void
        {
  var id:Number = 0;
  if (attributes != null && attributes.hasOwnProperty("id"))
  {
   id = attributes.id as Number;
  }
  else if (attributes is Number)
  {
   id = Number(attributes);
  }
                var idx:Object = configData.widgetIndex[id];
                var wgt:Object = configData.widgetContainers[idx.container].widgets[idx.widget];
                var preload:String = wgt.preload;
                var url:String = wgt.url;

                wgtInfo = ModuleManager.getModule(url);
                wgtInfo.data =
                    {
                        id: id,
                        preload: preload,
   attributes: attributes
                    };
                wgtInfo.addEventListener(ModuleEvent.READY, widgetReadyHandler);
                wgtInfo.addEventListener(ModuleEvent.ERROR, moduleErrorHandler);
                wgtInfo.load(null, null, null, moduleFactory);
                this.cursorManager.setBusyCursor();
            }

private function preloadNextWidget():void
            {
                if (preloadArray.length > 0)
                {
                    var id:Number = preloadArray[0].id;
                    preloadArray.splice(0, 1);
     var attr:Object = new Object();
     attr.id = id;
     AppEvent.dispatch(AppEvent.WIDGET_RUN, attr);
                }
            }

private function widgetReadyHandler(event:ModuleEvent):void
            {
                this.cursorManager.removeBusyCursor();

                var moduleInfo:IModuleInfo = event.module;
                moduleTable.add(moduleInfo.url, moduleInfo);

    var attr:Object = info.data as Object;
    runWidget(attr);
            }

/* HeaderControllerWidget.mxml */
 private function widgetItemDG_widgetItemClickHandler(event:Event):void
            {
                var widgetItem:WidgetItem = ItemRenderer(event.target).data as WidgetItem;
                if (widgetItem.isGroup)
                {
                    groupWidgetArrCol = new ArrayCollection();
                    // check the array of widgets if they are open before hand
                    for each (var widgetObj:Object in widgetItem.widgets)
                    {
                        var widgetItem1:WidgetItem = new WidgetItem;
                        widgetItem1.id = widgetObj.widget.id;
                        widgetItem1.label = widgetObj.widget.label;
                        widgetItem1.icon = widgetObj.widget.icon;
                        widgetItem1.url = widgetObj.widget.url;
                        widgetItem1.open = widgetObj.open;

                        groupWidgetArrCol.addItem(widgetItem1);
                    }
                    menuToolTip.visible = false;
                    widgetList.visible = true;
                }
                else
                {
     var attr:Object = new Object();
     attr.id = widgetItem.id;
     AppEvent.dispatch(AppEvent.WIDGET_RUN, attr);
                }
            }

            private function widgetList_widgetItemClickHandler(event:Event):void
            {
                var widgetItem:WidgetItem = ItemRenderer(event.target).data as WidgetItem;
    var attr:Object = new Object();
    attr.id = widgetItem.id;
    AppEvent.dispatch(AppEvent.WIDGET_RUN, attr);
            }


Sample here (2 widgets - 1-st send data = opens widget with additional attributes - 2-nd listen open handler and read attributes) with sources
0 Kudos
IvanBespalov
Frequent Contributor
Using Singleton class TransferDataManager.as:
package ee {  import flash.events.Event;  import flash.events.EventDispatcher;   [Event(name="onDataChanged", type="flash.events.Event")]  [Bindable]  public class TransferDataManager extends EventDispatcher  {   public static const TRANSFER_DATA_CHANGED:String = "onDataChanged";      private static var _instance:TransferDataManager;      /**    * @private    */   public function TransferDataManager(caller:Function = null)    {     if (caller != hidden)     throw new Error ("TransferDataManager is a singleton class, use getInstance() instead");        if (_instance != null)     throw new Error("Only one Singleton instance should be instantiated");   }      /**    * @return instance of ResourcesManager    *     */   public static function getInstance():TransferDataManager   {    if(!_instance)    {     _instance = new TransferDataManager(hidden);    }    return _instance;   }      /**    * @private    */   private static function hidden():void {}      public var transferedData:Object = null;      public function updateTransferData(obj:Object = null):void   {    transferedData = obj;    dispatchEvent(new Event(TRANSFER_DATA_CHANGED));   }  } }

define it firstly in top level component ViewerContainer.mxml:
<!---     Main application container. --> <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"          xmlns:s="library://ns.adobe.com/flex/spark"          width="100%" height="100%"  preinitialize="group1_preinitializeHandler(event)" ... protected function group1_preinitializeHandler(event:FlexEvent):void    {     initDataManager();    }        [Bindable]    private var transferManager:TransferDataManager;        protected function initDataManager():void    {     trace("ViewerContainer::initDataManager()");     transferManager = TransferDataManager.getInstance();    }

Create SenderWidget.mxml:
<?xml version="1.0" encoding="utf-8"?> <viewer:BaseWidget xmlns:fx="http://ns.adobe.com/mxml/2009"                    xmlns:s="library://ns.adobe.com/flex/spark"                    xmlns:mx="library://ns.adobe.com/flex/mx"                    xmlns:viewer="com.esri.viewer.*"        preinitialize="basewidget1_preinitializeHandler(event)">     <fx:Script>         <![CDATA[    import ee.TransferDataManager;           import mx.events.FlexEvent;        [Bindable]    private var transferManager:TransferDataManager;     protected function button1_clickHandler(event:MouseEvent):void    {     trace("SenderWidget::button1_clickHandler()");     // create some data you wand to pass     var transferData:Object = new Object();     transferData.message = txtInput.text;     transferData.date = new Date();          // get transfer manager instance     transferManager = TransferDataManager.getInstance();     transferManager.updateTransferData(transferData);       }        protected function basewidget1_preinitializeHandler(event:FlexEvent):void    {     initDataManager();    }        protected function initDataManager():void    {     trace("SenderWidget::initDataManager()");     transferManager = TransferDataManager.getInstance();     transferManager.addEventListener(TransferDataManager.TRANSFER_DATA_CHANGED, onTransferDataChanged);    }        protected function onTransferDataChanged(event:Event):void    {     trace("SenderWidget::onTransferDataChanged()");    }          ]]>     </fx:Script>     <viewer:WidgetTemplate id="senderWidget"                            width="300" height="300">         <viewer:layout>             <s:VerticalLayout horizontalAlign="center" verticalAlign="middle"/>         </viewer:layout>          <s:TextInput id="txtInput" />   <s:Button label="Send" click="button1_clickHandler(event)" />     </viewer:WidgetTemplate> </viewer:BaseWidget>

and RecieverWidget.mxml:
<?xml version="1.0" encoding="utf-8"?> <viewer:BaseWidget xmlns:fx="http://ns.adobe.com/mxml/2009"                    xmlns:s="library://ns.adobe.com/flex/spark"                    xmlns:mx="library://ns.adobe.com/flex/mx"                    xmlns:viewer="com.esri.viewer.*"        preinitialize="basewidget1_preinitializeHandler(event)">     <fx:Script>         <![CDATA[    import ee.TransferDataManager;        import mx.events.FlexEvent;    import mx.utils.StringUtil;        [Bindable]    private var transferManager:TransferDataManager;     protected function basewidget1_preinitializeHandler(event:FlexEvent):void    {     trace("RecieverWidget::basewidget1_preinitializeHandler()");     initDataManager();    }        protected function initDataManager():void    {     trace("RecieverWidget::initDataManager()");     transferManager = TransferDataManager.getInstance();     transferManager.addEventListener(TransferDataManager.TRANSFER_DATA_CHANGED, onTransferDataChanged);     var transferedData:Object = transferManager.transferedData;          if (transferedData)     {      if (transferedData.hasOwnProperty("message") && transferedData.hasOwnProperty("date"))      {       var msg:String = StringUtil.substitute("{0} -> {1}", transferedData.message, transferedData.date);       writeLog(msg);      }     }    }        protected function onTransferDataChanged(event:Event):void    {     trace("RecieverWidget::onTransferDataChanged()");     transferManager = TransferDataManager.getInstance();     var transferedData:Object = transferManager.transferedData;          if (transferedData)     {      if (transferedData.hasOwnProperty("message") && transferedData.hasOwnProperty("date"))      {       var msg:String = StringUtil.substitute("{0} -> {1}", transferedData.message, transferedData.date);       writeLog(msg);      }     }    }        private function writeLog(message:String):void    {     trace("RecieverWidget::writeLog()");     log.text = StringUtil.substitute("{0}\n{1}", message, log.text);    }          ]]>     </fx:Script>     <viewer:WidgetTemplate id="recieverWidget"                            width="300" height="300">         <viewer:layout>             <s:VerticalLayout horizontalAlign="center" verticalAlign="middle"/>         </viewer:layout>      <s:TextArea width="100%" height="100%" id="log" />     </viewer:WidgetTemplate> </viewer:BaseWidget>


Sender and Receiver - is conditional. It can work in reverse mode.
0 Kudos
HelioHiroshi
Deactivated User
Thanks! Ivan.
This helped a lot.
0 Kudos