Select to view content in your preferred language

Best practice for moving between multiple editors?

969
5
07-27-2010 01:59 PM
RoyceSimpson
Frequent Contributor
I've got three feature layers (point, line and polygon) that I'd like to split out into three different editors so that I can have each editor in it's own tab in a Tab Navigator.  I've implemented the following mxml:


<mx:TabNavigator id="tabNavigator" width="251" height="347" x="10" y="10" change="setEditor(event)"
      creationPolicy="auto">
  <s:NavigatorContent id="pointsTab" label="Points" width="100%" height="100%">
   <esri:Editor id="pointsEditor" height="100%" width="100%" map="{map}" toolbarVisible="true" featureLayers="{[map.getLayer('TypePointsLayer') as FeatureLayer]}"/>
  </s:NavigatorContent>
  <s:NavigatorContent id="linesTab" label="Lines" width="100%" height="100%" >
   <esri:Editor id="linesEditor" height="100%" width="100%" map="{map}" toolbarVisible="true" featureLayers="{[map.getLayer('TypeLinesLayer') as FeatureLayer]}"/>
  </s:NavigatorContent>
  <s:NavigatorContent id="areasTab" label="Areas" width="100%" height="100%" >
   <esri:Editor id="areasEditor" height="100%" width="100%" map="{map}" toolbarVisible="true" featureLayers="{[map.getLayer('TypePolysLayer') as FeatureLayer]}"
       geometryService="{new GeometryService(_geometryURL)}"/>
  </s:NavigatorContent>
</mx:TabNavigator>

The problem is, as I go from one tab to the next, each editor becomes active and editing mayhem kicks in.  So, I added a "change event" to the tab navigator with the following code:

   private function setEditor(event:IndexChangedEvent):void
   {
    for each (var layer:Layer in map.layers)
    {
     if (layer is FeatureLayer)
     {
      var fl:FeatureLayer = layer as FeatureLayer;
      if (fl.selectedFeatures.length > 0)
      {
       fl.clearSelection();
      }
     }
    }
   
    var i:int = event.target.selectedIndex;   
    switch(i)
    {
     case 0:
     {
      if(linesEditor)
      {
       linesEditor.editTool.deactivate();
       linesEditor.templatePicker.clearSelection();
      }
      if(areasEditor)
      {
       areasEditor.editTool.deactivate();
       areasEditor.templatePicker.clearSelection();
      }
      break;
     }
     case 1:
     {
      if(pointsEditor)
      {
       pointsEditor.editTool.deactivate();
       pointsEditor.templatePicker.clearSelection();
      
      }
     
      if(areasEditor)
      {
       areasEditor.editTool.deactivate();
       areasEditor.templatePicker.clearSelection();
      }
      break;
     }
     case 2:
     {
      if(pointsEditor)
      {
       pointsEditor.editTool.deactivate();
       pointsEditor.templatePicker.clearSelection();
      }
      if(linesEditor)
      {
       linesEditor.editTool.deactivate();
       linesEditor.templatePicker.clearSelection();
      }
      break;
     }
    }
   }

This doesn't work for some reason.  The "deactivate" method on the editTool for the editors that I'd like to "disable" don't seem to do any deactivating.  For example if I have the "line editor" tab active, I'd like to deactivate the "point editor edittool" and "poly editor edittool" so that the user can't click/select/edit existing points or polys.

Maybe there is a better approach to doing this.

Thanks for any advice.
-r
Tags (2)
0 Kudos
5 Replies
SarthakDatt
Frequent Contributor
Hey Royce,

If this is just a view thing, then that is not the way to do it.

The Editor component right now uses the TemplatePicker to showcase different featureLayers.
With Flex 4, the new skinning architecture provides a clean separation between the logic and visual elements of a component.Hence, in order to show your featureLayers as different tabs in a TabNavigator, you could create your own skin for the TemplatePicker(which has the TabNavigator) and apply that instead of the default skin(which come out of the box with the api).

You can look at : http://help.arcgis.com/en/webapi/flex/help/index.html
and go to "Inside the API" -> "Styling and Skinning - Overview" and learn more about it.

Heres another article on flex 4 skinning : http://www.adobe.com/devnet/flex/articles/flex4_skinning.html

Hope that helps.

--Sarthak Datt
ESRI Flex Team
0 Kudos
RoyceSimpson
Frequent Contributor
Hi Sarthak,
I actually am using the editors in each tab for editing.  So, instead of having each of the three feature layers come up in a single editor where the user would have to scroll down through the layers and each layer's designated templates to get to the features they want, I'd like to break out the three feature layers into their own editors and put each of those into their own tab in tab navigator. 
Hopefully that makes sense.

As an example, if you take a look at the ESRI Editing "Editor with toolbar" sample, there are two feature layers:  "points of interest" and "fire perimeter".  If I wanted to break up those two layers to be handled by two separate editors in a tab navigator where one tab got "points of interest" and the other tab got "fire perimeter"... how would you go about best implementing that such that when you invoked the editor on each tab, the other editor isn't activated at the same time?

I'll see if one of my sys admins will open up the server to be accessible from outside the firewall so you can inspect things directly.

-r
0 Kudos
SarthakDatt
Frequent Contributor
Hey Royce,

I did a quick modification to the sample you mentioned. This is how it looks:

<?xml version="1.0" encoding="utf-8"?>
<s:Application 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:esri="http://www.esri.com/2008/ags"
               pageTitle="Editor component with toolbar">

    <fx:Script>
        <![CDATA[
            import mx.events.IndexChangedEvent;

            protected function tabNavigator_changeHandler(event:IndexChangedEvent):void
            {
                switch(event.target.selectedIndex)
                {
                    case 0:
                        if(areasEditor)
                        {   
                            // clean up the areasEditor
                            for each (var featureLayer:FeatureLayer in areasEditor.featureLayers)
                            {
                                if (featureLayer.selectedFeatures.length > 0)
                                {
                                    featureLayer.clearSelection();
                                }
                            }
                            areasEditor.map = null;
                            areasEditor.featureLayers = null;
                            areasEditor.drawTool.deactivate();
                            areasEditor.editTool.deactivate();
                            areasEditor.templatePicker.clearSelection();
                            
                            // assign back, if cleaned up      
                            pointsEditor.map = myMap;
                            pointsEditor.featureLayers = [points];
                        }
                        break;                  
                    case 1:
                        if(pointsEditor)
                        {   
                            // clean up the pointsEditor
                            for each (var featureLayer1:FeatureLayer in pointsEditor.featureLayers)
                            {
                                if (featureLayer1.selectedFeatures.length > 0)
                                {
                                    featureLayer1.clearSelection();
                                }
                            }
                            pointsEditor.map = null;
                            pointsEditor.featureLayers = null;
                            pointsEditor.drawTool.deactivate();
                            pointsEditor.editTool.deactivate();
                            pointsEditor.templatePicker.clearSelection();
                            
                            // assign back, if cleaned up                           
                            areasEditor.map = myMap;
                            areasEditor.featureLayers = [fireAreas];
                        }
                        break;
                }
            }
        ]]>
    </fx:Script>

    <mx:HBox height="100%" width="100%">
        <mx:TabNavigator id="tabNavigator" width="251" height="347" x="10" y="10" change="tabNavigator_changeHandler(event)"
            creationPolicy="auto">
            <s:NavigatorContent id="pointsTab" label="Points" width="100%" height="100%">
                <esri:Editor id="pointsEditor" height="100%" width="100%" map="{myMap}" toolbarVisible="true" featureLayers="{[points]}"/>
            </s:NavigatorContent>
            <s:NavigatorContent id="areasTab" label="Areas" width="100%" height="100%" >
                <esri:Editor id="areasEditor" height="100%" width="100%" map="{myMap}" toolbarVisible="true" featureLayers="{[fireAreas]}"/>
            </s:NavigatorContent>
        </mx:TabNavigator>
        <esri:Map id="myMap">
            <esri:extent>
                <esri:Extent id="sheepfire"
                             xmin="-13144000" ymin="4033000" xmax="-13066000" ymax="4099000">
                    <esri:SpatialReference wkid="102100"/>
                </esri:Extent>
            </esri:extent>
            <esri:ArcGISTiledMapServiceLayer url="http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer"/>
            <esri:FeatureLayer id="points"
                               mode="snapshot"
                               outFields="*"
                               url="http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Fire/Sheep/FeatureServer/0"/>
            <esri:FeatureLayer id="fireAreas"
                               mode="snapshot"
                               outFields="*"
                               url="http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Fire/Sheep/FeatureServer/2"/>
        </esri:Map>
    </mx:HBox>
</s:Application>


Let me know if this works for you.

--Sarthak Datt
0 Kudos
RoyceSimpson
Frequent Contributor
Thanks!  Works now.  Needed to add the "= null" assignments and then add the stuff for assigning back the map and feature layers.

Do you think this is a decent solution or would it be better to only have one editor and do some skinning with the TabNavigator?  I like this because it separates out the editing of each of the layers.  Gives the user more fine grained control..
0 Kudos
SarthakDatt
Frequent Contributor
Yes it gives you a more fine grain control...however maintaining several instances of the editor would always be a pain. I know, in real world an app wont have that many featureLayers...but still.

You could follow the skinning approach. An example would be when you are working with one feature Layer...you could disable/hide the other or show a message so that users could not/wont use it. The default skin(TemplatePickerSkin) does something like that now if a featureLayer is invisible/out of scale range.

Having said that, from an API perspective, I think it would be better if we had something like a clear() or destroy() on the editor, so that users wont have to worry about cleaning it up themselves.

--Sarthak Datt
0 Kudos