spliting code into components: good examples?

671
6
Jump to solution
03-26-2012 07:18 AM
ErikMartin
Occasional Contributor
I am working on developing a custom widget that performs a geoprocessing task.  I have a first iteration of it working-- it returns a point layer and symbolizes it.  The code is currently all in one MXML file and is a bit ungainly.  A lot of code is taken up for the UniqueValueRenderer and I would like to split this out into a separate component to make the code more readable, and also to simplify its reuse.  I am struggling to figure out the best way to do this.  The UniqueValueRenderer is written in MXML.   When I split this out into a separate component MXML, I am not sure how to access it in the main file ActionScript.

Specifically, I've got ResultRenderer.mxml with the following (this is shortened):

<fx:Declarations>   <esri:SimpleMarkerSymbol    id="tier1"    color="0xFF0000"    size="12">    <esri:SimpleLineSymbol      width="1"      color="0x000000"/>   </esri:SimpleMarkerSymbol>   <esri:SimpleMarkerSymbol    id="tier2"    color="0xFF4400"    size="12">    <esri:SimpleLineSymbol      width="1"      color="0x000000"/>                  <esri:UniqueValueRenderer id="uniqueValueRenderer" field="Tier">    <esri:UniqueValueInfo symbol="{tier1}" value="1"/>    <esri:UniqueValueInfo symbol="{tier2}" value="2"/>                 </esri:UniqueValueRenderer> </fx:Declarations>



Then in my main mxml, I want to call it here (4th line), but I get an undefined property error.  Any insight or example would be appreciated!
   protected function onGetResult(event : GeoprocessorEvent) : void    {          var myGraphicsLayer:GraphicsLayer = new GraphicsLayer();     myGraphicsLayer.renderer = ResultRenderer.uniqueValueRenderer;     var pv:ParameterValue = event.parameterValue;     var fs:FeatureSet = pv.value as FeatureSet;      for each(var graphic:Graphic in fs.features)     {     myGraphicsLayer.add(graphic);     }      map.addLayer(myGraphicsLayer);           CursorManager.removeBusyCursor();    }
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus
Erik,

   I didn't have any time to test this but this is more along the lines of what I was thinking:

package widgets.MyWidget.components {     import com.esri.ags.renderers.UniqueValueRenderer;     import com.esri.ags.renderers.supportClasses.UniqueValueInfo;     import com.esri.ags.symbols.SimpleMarkerSymbol;          public class ResultRenderer     {         public function ResultRenderer():UniqueValueRenderer         {             var resultPointSym:UniqueValueRenderer = new UniqueValueRenderer();             var tier1:SimpleMarkerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 12, 0xFF0000);             var tier2:SimpleMarkerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 12, 0xFF4400);                          resultPointSym.field = "Tier";             var resultPointSymInfos:Array=[];             resultPointSymInfos.push(new UniqueValueInfo(tier1, "1"));             resultPointSymInfos.push(new UniqueValueInfo(tier2, "2"));             resultPointSym.infos = resultPointSymInfos;             return resultPointSym;         }     } }

View solution in original post

0 Kudos
6 Replies
RobertScheitlin__GISP
MVP Emeritus
Erik,

   What kind of other stuff doe you have in your ResultRenderer.mxml? If you convert this to a Action Script class (.as) and declare public vars in actionscript for the uniqueValueRenderer and other stuff you currently have in mxml, then you can import the ResultRenderer.as and call the public vars.

Don't forget to click the Mark as answer check on this post and to click the top arrow (promote) as shown below:
0 Kudos
ErikMartin
Occasional Contributor
What I posted is basically all the ResultRenderer.mxml has-- it just has more of it: there's around 20 different breaks instead of 2, but they all describe the one unqiueValueRenderer (at this point anyway).

I will try converting it from mxml to ActionScript as you suggest & post back with the result.  Thanks for your help!
-Erik
0 Kudos
ErikMartin
Occasional Contributor
Robert / other Flex gurus,
I believe I am on the right track, but am stuck again (if it isn't obvious, I'm new to Flex...)  I have migrated the uniqueValueRenderer to ActionScript, but have not been able to successfully call the renderer and get it to work.  Here's my AS in the component file:

package widgets.MyWidget.components
{
 import com.esri.ags.renderers.UniqueValueRenderer;
 import com.esri.ags.renderers.supportClasses.UniqueValueInfo;
 import com.esri.ags.symbols.SimpleMarkerSymbol;
  
 public class ResultRenderer extends UniqueValueRenderer
 {
  public  static var resultPointSym:UniqueValueRenderer = new UniqueValueRenderer();
  public function ResultRenderer()
  {
   super();
 
   var tier1:SimpleMarkerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 12, 0xFF0000);
   var tier2:SimpleMarkerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 12, 0xFF4400);

   resultPointSym.field = "Tier";
   var resultPointSymInfos:Array=[];
   resultPointSymInfos.push(new UniqueValueInfo(tier1, "1"));
   resultPointSymInfos.push(new UniqueValueInfo(tier2, "2"));
                        resultPointSym.infos = resultPointSymInfos;
  }
 }
}


And the pertinent script in the main file:

  
                         import widgets.MyWidget.components.ResultRenderer;  
                         protected function onGetResult(event : GeoprocessorEvent) : void
   {     
    var myGraphicsLayer:GraphicsLayer = new GraphicsLayer();
    myGraphicsLayer.renderer = ResultRenderer.resultPointSym;
    var pv:ParameterValue = event.parameterValue;
    var fs:FeatureSet = pv.value as FeatureSet;
    
    for each(var graphic:Graphic in fs.features)
    {
     myGraphicsLayer.add(graphic);
    } 
    map.addLayer(myGraphicsLayer); 
    
    CursorManager.removeBusyCursor();
   }

Flex Builder gives no errors and successfully compiles the code, but the results aren't rendered.  (I can see via Firebug that the results are returned... the JSON looks just as it's supposed to & the field name in the AS is correct).

Again, many thanks for any help or guidance.  As a more general question, are there any widgets that do a particularly good job of splitting functionality into components like this & which might be useful examples? 
Thanks!
-Erik
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Erik,

   I didn't have any time to test this but this is more along the lines of what I was thinking:

package widgets.MyWidget.components {     import com.esri.ags.renderers.UniqueValueRenderer;     import com.esri.ags.renderers.supportClasses.UniqueValueInfo;     import com.esri.ags.symbols.SimpleMarkerSymbol;          public class ResultRenderer     {         public function ResultRenderer():UniqueValueRenderer         {             var resultPointSym:UniqueValueRenderer = new UniqueValueRenderer();             var tier1:SimpleMarkerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 12, 0xFF0000);             var tier2:SimpleMarkerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 12, 0xFF4400);                          resultPointSym.field = "Tier";             var resultPointSymInfos:Array=[];             resultPointSymInfos.push(new UniqueValueInfo(tier1, "1"));             resultPointSymInfos.push(new UniqueValueInfo(tier2, "2"));             resultPointSym.infos = resultPointSymInfos;             return resultPointSym;         }     } }
0 Kudos
GeorgiaHalsted
New Contributor
thanks for sharing
0 Kudos
ErikMartin
Occasional Contributor
Thanks, Robert.  That sent me down the right path.  Here's the final code... It is nearly what you wrote, but I don't make it a class-- when it is a class the following error is thrown in Flash Builder:  1130: A constructor cannot specify a return type.  From this, I gather I could have had an empty constructor then added in the function of interest as a separate function.  What I did, though, was just to remove the constructor so it is a function in a standalone AS file.  For the record, here's the final code:

package widgets.MyWidget.components
{
 import com.esri.ags.renderers.UniqueValueRenderer;
 import com.esri.ags.renderers.supportClasses.UniqueValueInfo;
 import com.esri.ags.symbols.SimpleMarkerSymbol;
 
  public function ResultRenderer():UniqueValueRenderer
  { 
   var resultPointSym:UniqueValueRenderer = new UniqueValueRenderer();
   var tier1:SimpleMarkerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 12, 0xFF0000);
   var tier2:SimpleMarkerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 12, 0xFF4400);

   resultPointSym.field = "Tier";
   var resultPointSymInfos:Array=[];
   resultPointSymInfos.push(new UniqueValueInfo(tier1, "1"));
   resultPointSymInfos.push(new UniqueValueInfo(tier2, "2"));

   resultPointSym.infos = resultPointSymInfos;
   return resultPointSym;
 }
}


And then in the main mxml:

   
                        import widgets.MyWidget.components.ResultRenderer; 

                        protected function onGetResult(event : GeoprocessorEvent) : void
   {     
    var myGraphicsLayer:GraphicsLayer = new GraphicsLayer();
    myGraphicsLayer.renderer = ResultRenderer();
    var pv:ParameterValue = event.parameterValue;
    var fs:FeatureSet = pv.value as FeatureSet;
    
    for each(var graphic:Graphic in fs.features)
    {
     myGraphicsLayer.add(graphic);
    } 
    map.addLayer(myGraphicsLayer); 
    
    CursorManager.removeBusyCursor();
   }


Again, many thanks for your help!
-Erik
0 Kudos