Extending the ArcGIS Javascript API

November 8, 2008

Working with the new Javascript API for ArcGIS Server 9.3, I am now writing quite a bit of javascript. If you try and write large amounts of javascript code (I would consider >200 lines as large enough) without using objects, soon enough you’re going to have an unreadable nightmare in your hands.

In order for the code to be maintainable, I’ve realized I have to take advantage of dojo’s object-orientation capabilities, and especially inheritance. This allows me to extend ESRI’s default objects, compensate for missing behaviors, and add logic of my own. Luckily, in javascript the can’t mark their objects sealed, or need to remember to mark methods as “virtual”, so extending this API’s objects is easier than doing so in the ADF.

For instance, suppose you want an ArcGISDynamicMapServiceLayer to tell you which layers are currently visible for it. Thing is, the API only exposes a setVisibleLayers method, but not a getVisibleLayers(). So let’s try and add this, shall we?

1 //doron.common.js 2 dojo.require("esri.map"); 3 4 dojo.declare("Doron.ExtendedDynamicMapServiceLayer", esri.layers.ArcGISDynamicMapServiceLayer, { 5 constructor: function () { 6 dojo.connect(this, "onLoad", function () { 7 this._currentVisibleLayers = this._getDefaultVisibleLayers(); 8 }); 9 }, 10 setVisibleLayers: function(layers) { 11 this._currentVisibleLayers = layers; 12 //dojo's way of calling base method - so that default behavior is preserved 13 this.inherited(arguments); 14 15 }, 16 getCurrentVisibleLayers: function() { 17 return this._currentVisibleLayers; 18 }, 19 _getDefaultVisibleLayers: function () { 20 var defaultVisibleLayers = []; 21 for (var i=0; i < this.layerInfos.length; i++) { 22 if (this.layerInfos[i].defaultVisibility) 23 defaultVisibleLayers.push(this.layerInfos[i].id); 24 } 25 return defaultVisibleLayers; 26 } 27 });

I am using dojo.declare to declare my new class, which inherits from esri.layers.ArcGISDynamicMapServiceLayer. My constructor first saves the layers that are visible by default in a field (this can only be done once the layer is loaded, so I’m registering myself to that event). I also override setVisibleLayers(), so that when it is called, I remember to update that field as well.  Now I can easily expose the getCurrentVisbleLayers() method.

This class is something you can put in a .js file and reference everywhere you want – it is a much better approach than putting all your scripts inside the .html/.aspx/.whatever file.

A page that would use it, might look like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Dynamically Create Map Service Layer List</title> <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/1.1/js/dojo/dijit/themes/tundra/tundra.css"> <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=1.1"></script> <script type="text/javascript" src="doron.common.js"></script> <script type="text/javascript"> dojo.require("esri.map"); function init() { map = new esri.Map("map"); layer = new Doron.ExtendedDynamicMapServiceLayer("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer"); map.addLayer(layer); } function showVisibleLayers() { alert( layer.getCurrentVisibleLayers().join(',')); } dojo.addOnLoad(init); </script> </head> <body> <div id="map" class="tundra" style="width:600px; height:400px; border:1px solid #000;"></div> <input type="button" onclick="showVisibleLayers()" value="Show Visible Layers" /> </body> </html>

Here I just took one of ESRI’s samples, and replaced their class with mine. I also added a button that shows the layers that are currently visible. The reference to “doron.common.js” allows me to use my own class that overrides the ESRI one. 

Hope this was helpful. If you know of any more ways to make life with the Javascript API more comfortable, feel free to share.

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

6 comments

  1. davidgshiNovember 19, 2008 ב 12:25

    Hello, there. Have you got a good example to pass parameters into a Javascript function and fire off a server-end geoprocessor to run, monitor its progress. Upon completion, set back an innerHTML to tell the user the job is done.

    I have been having problems with firing off a 2 to 3 minutes geoprocessor.

    Thank you very much in advance for your help.

    Regards.

    David
    davidgshi@yahoo.co.uk

    Reply
  2. doronyNovember 19, 2008 ב 12:35

    Hi David,
    I haven’t tried anything of the sort, but if you can elaborate on which problems you’re having, maybe I can help you out.

    Reply
  3. DavidNovember 20, 2008 ב 6:42

    Dear Dorony,

    Can I have your email address? I can not send you attachment in this.

    Regards.

    David
    davidgshi@yahoo.co.uk

    Reply
  4. doronyNovember 21, 2008 ב 7:52

    Hi David, you can contact me via the “Contact” link on the top left of this blog. You should also be careful about publishing your mail on a blog comments thread – as it might invite spammers to spam you.

    Reply
  5. krystianMay 14, 2012 ב 12:24

    great article thanks!! 🙂

    Reply
  6. McneilJuly 30, 2012 ב 4:44

    thanks heaps, wonderful post

    Reply