浅谈关于Dojo在ArcGIS API For JS应用

说来我学习ArcGIS API也有快一年了,从刚开始的懵懂无知,到自认为还是有点自我看法,前一段时间有个学弟问我,为什么ArcGIS API For JS为什么会基于Dojo开发呢?给他解释了一通也不知道他理解了没有,所以在这里写一篇文章谈谈自己的看法。

一、关于 gis api

首先api是一款类库存在(组件式开发,可能这么不太合适),每个类中都有自己的方法,方法等,涉及到类,就涉及到继承,一个可能需要继承多个,在C#类的多继承是通过接口来实现,而javascript属于原型继承,与强类型的继承有很大的区别,在JavaScript中每个函数(在js中函数即对象)对象都有一个prototype属性,这个属性指向的对象就是这个函数对象的的原型对象(即父类),这个原型对象也有prototype属性,默认指向该原型对象的父类,就这样一级一级形成所谓的原型链这就是原型链的由来,使用原型继承有几个缺点:

  • 原型只能为某一个对象,不能设为多个对象(即prototype属性只能指向一个父类),所以不支持多继承
  • 原型中的属性为多个子类多共享,如果某个子类修改了原型中的某一个属性值,则其他子类也会受影响
  • 原型的设置只能发生在对象都构造完成之后,这样会造成在子类的对象的构造函数中无法修改父类对象的属性,而在基于类的继承中,子类对象在自己的构造函数中可以调用父类的构造函数

为了解决上述问题dojo在js已有的原型的继承机制上进行进一步的封装,可以实现单继承,多继承,这也是dojo的厉害之处,dojo可以快速布局化,这个算是开发效率的方式,使开发人员可以实现快速进行布局,本人没怎么用过,况且还那么丑,还是自己布局好点,况且HTML5有好多布局模块可用,在arcgis api声明自己的模块的时候要用dojo这是他的特色我们应该好好利用。

二、自定义模块

define(["dojo/_base/declare"],function(declare){
return declare(
    //类名省略
null,//无父类用null,
{    
     firstName: "",
     middleName: "",
     lastName: "",
     constructor: function (fName, mName, lName) {//构造函数
        this.firstName = fName;
        this.middleName = mName;
        this.lastName = lName;
    },
    buyBook: function (bookName, num) {
        alert(firstName + " " + middleName + " " + lastName + " want to buy " + num + " " + bookName);
    }
}
);
 });

define用于定义模块,"dojo/_base/declare"是所以依赖的模块可以有多个。

 

      1.第一个参数className为类名,如示例中的custom.javaworld.Student;

     2.第二个参数为该类的父类,dojo中提供了多重继承,当有多个父类时,使用[superClass1,superClass2,...]格式,示例中值为null,因为该类不继承自任何类;

 return 某个值(属性 函数 或者对象 如果没有return 那加载不出来什么)

三、自定义模块示例

define(["dojo/_base/declare",
    "esri/layers/tiled"],
    function (declare) {
        return declare(esri.layers.TiledMapServiceLayer, {
            constructor: function () {
                this.spatialReference = new esri.SpatialReference({ wkid: 4326 });
                this.initialExtent = (this.fullExtent = new esri.geometry.Extent(-180.0, -90.0, 180.0, 90.0, this.spatialReference));
                this.tileInfo = new esri.layers.TileInfo({
                    "rows": 256,
                    "cols": 256,
                    "compressionQuality": 0,
                    "origin": {
                        "x": -180,
                        "y": 90
                    },
                    "spatialReference": {
                        "wkid": 4326
                    },
                    "lods": [
                        { "level": 2, "resolution": 0.3515625, "scale": 147748796.52937502 },
                        { "level": 3, "resolution": 0.17578125, "scale": 73874398.264687508 },
                        { "level": 4, "resolution": 0.087890625, "scale": 36937199.132343754 },
                        { "level": 5, "resolution": 0.0439453125, "scale": 18468599.566171877 },
                        { "level": 6, "resolution": 0.02197265625, "scale": 9234299.7830859385 },
                        { "level": 7, "resolution": 0.010986328125, "scale": 4617149.8915429693 },
                        { "level": 8, "resolution": 0.0054931640625, "scale": 2308574.9457714846 },
                        { "level": 9, "resolution": 0.00274658203125, "scale": 1154287.4728857423 },
                        { "level": 10, "resolution": 0.001373291015625, "scale": 577143.73644287116 },
                        { "level": 11, "resolution": 0.0006866455078125, "scale": 288571.86822143558 },
                        { "level": 12, "resolution": 0.00034332275390625, "scale": 144285.93411071779 },
                        { "level": 13, "resolution": 0.000171661376953125, "scale": 72142.967055358895 },
                        { "level": 14, "resolution": 8.58306884765625e-005, "scale": 36071.483527679447 },
                        { "level": 15, "resolution": 4.291534423828125e-005, "scale": 18035.741763839724 },
                        { "level": 16, "resolution": 2.1457672119140625e-005, "scale": 9017.8708819198619 },
                        { "level": 17, "resolution": 1.0728836059570313e-005, "scale": 4508.9354409599309 },
                        { "level": 18, "resolution": 5.3644180297851563e-006, "scale": 2254.4677204799655 }
                    ]
                });
                this.loaded = true;
                this.onLoad(this);
            },
            getTileUrl: function (level, row, col) {
                return "http://t" + row % 8 + ".tianditu.cn/cva_c/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=c&TILEMATRIX=" + level + "&TILEROW=" + row + "&TILECOL=" + col + "&FORMAT=tiles";
            }
        });
    });

四、如果引用自定义模块

1、dojoConfig参数解释

var dojoConfig = {
    baseUrl: "/js",
    has: {
        //用于定义dojo的火狐浏览器bug检测模块
        "dojo-firebug": true,
        "dojo-debug-messages": true
    },
    //用于定义dojo核心示范异步加载,true:异步,false:同步
    async: true,
    //如果为true则立即加载deps数组中所有的依赖JS,如果为false则忽略deps数组
    parseOnLoad: false,
    //用于页面加载时立即加载的JS依赖
    deps: ["dojo/parser"],
    //这个方法与deps关联,执行这个回调方法直到deps项加载完毕
    callback: function(parser) {},
    //加载一个模块的请求超时时间,如果超时说明加载模块失败
    waitSeconds: 5,
    //如果为true可以避免模块缓存(原理就是在请求模块的URL加上当前时间戳)
    cacheBust: true
}

2、加载模式

  • 通过packages数组进行定义预置AMD模块

//name是该模块标识符名称,localtion为模块所在的路径
var dojoConfig = {
    packages: [
        { name: "package1", location: "../lib/package1" },
        { name: "package2", location: "/js/package2" }
    ]
};

如果这个模块的路径是在根目录下的子目录,我们可以这样定义:

//获取当前项目根目录+模块所在目录
 packages: [{
        name: "js",
        location: location.pathname.replace(/\/[^/]*$/, '') + '/js'
    }]

这种方式加载最为常用,可以引入多个模块,dojoConfig配置必须放在arcgis api的js文件之前否则会出错,

五、在require引入示例

    <script type="text/javascript">
        var path = this.location.pathname.replace(/\/[^/]+$/, "");
        var dojoConfig = {
            parseOnLoad: true,
            packages: [{
                "name": "MapCluster",
                "location": path + "/lib"
            }]//都在一个位置写一个即可
        };
    </script>
    <script src="https://js.arcgis.com/3.24/"></script>
<!--    <script src="http://localhost/arcgis_js_api/library/3.20/3.20/init.js"></script>-->
    <!--<script src="../../../Scripts/jquery-1.7.1.js"></script>-->
    <!--<script src="../../../Scripts/jsapi_vsdoc12_v38.js"></script>-->
    <script src="data.js"></script>
    <script type="text/javascript">
        var map;
        var data = [];
        var currpage = 1, pagesize = 10, total = 1000;
        var pagenum = total / pagesize;
        if (total / pagesize != 0) {
            pagenum = parseInt(total / pagesize) + 1;
        }
        require(["dojo/parser",
                    "esri/SpatialReference",
                    "dojo/_base/array",
                    "esri/map",
                    "esri/layers/ArcGISTiledMapServiceLayer",
                    "esri/geometry/Point",
                    "esri/layers/GraphicsLayer",
                    "MapCluster/ClusterLayer",
                    "MapCluster/BDAnoLayer",
                    "MapCluster/BDImgLayer",
                    "MapCluster/BDVecLayer",
                     "MapCluster/TDTTilesLayer",
                    "esri/graphic",
                    "esri/symbols/SimpleMarkerSymbol",
                    "esri/symbols/SimpleLineSymbol",
                    "esri/symbols/SimpleFillSymbol",
                    "esri/renderers/ClassBreaksRenderer",
                    "dojo/_base/Color",
                    "esri/geometry/webMercatorUtils",
                    "dojo/domReady!"],
                function (parser,
                    SpatialReference,
                          arrayUtils,
                          Map,
                          Tiled,
                          Point,
                          GraphicsLayer,
                          ClusterLayer,
                          BDAnoLayer,
                          BDImgLayer,
                          BDVecLayer,
                          TDTTilesLayer,
                          Graphic,
                          SimpleMarkerSymbol,
                          SimpleLineSymbol,
                          SimpleFillSymbol,
                          ClassBreaksRenderer,
                          Color,
                          webMercatorUtils) {

红线标注是在require中引入,因为四个自定模块都在一个文件下,所以在dojoConfig配置一项即可。

 

posted @ 2018-07-14 18:24  HPUGIS  阅读(1368)  评论(0编辑  收藏  举报