Dojo学习之Class(类)

前端之家收集整理的这篇文章主要介绍了Dojo学习之Class(类)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

转载自:http://blog.csdn.net/lovecarpenter/article/details/53981357

1.引言

说到面向对象,我们就不得不提一下类,在原生的js中我们是不可以创建类的,没有class这个关键字,但是在dojo中,dojo自定义了一个模块叫做dojo/_base/declare,用这个模块我们可以创建自己的类,实现面向对象编程。在本篇博客中我们就来学习一下如何在我们应用程序中使用dojo/_base/declare创建类。

2.dojo中的类

首先我们先看一下dojo/_base/declare声明:

      • 1
        • 1
        declare(classname,[],{})
      • declare的第一个参数是可选的,代表类的名称
      • declare的第二个参数代表类的继承关系,比如继承哪一个父类,可以看到:第二个参数是一个数组,所以dojo可以多继承
      • 第三个参数是一个对象,代表类的主体。

      2.1创建一个简单的类

      说完了类的继承,那么我们就创建一个非常简单的类:

      1. 1
      2. 2
      3. 3
      4. 4
      5. 5
      6. 6
      7. 7
      8. 8
      9. 9
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          var Person=declare("namespace.Person",null,{
        • name:function(name,age){
        • this.name=name;
        • this.age=age;
        • }
        •  
        • });
        • 上述代码建立了一个Person类,没有父类,构造函数为constructor
        • 我们如何创建一个Person类的实例呢?代码var p=new Person("wpx",20)

        上面的方法是很简单的一个类,但是有一个问题,如果类的属性特别多,那么我们构造函数里面的参数就会很多,有没有一种解决方法呢?答案是有的。现在看修改之后的代码

        1. 1
        2. 2
        3. 3
        4. 4
        5. 5
        6. 6
        7. 7
        8. 8
            • 1
            • 2
            • 3
            • 4
            • 5
            • 6
            • 7
            • 8
            (args){
          • declare.safeMixin(this,args);
          • }
          •  
          • });

          那么我们在创建类的实例时,应该怎么办呢?代码:

          1. 1
          2. 2
          3. 3
          4. 4
              • 1
              • 2
              • 3
              • 4
              var p=new Person({
            • name:"wpx",age:20
            • })

            此时可能有朋友问了,类名有什么作用呢??类名可以用作类的全局引用比如上面的Person类还可以这样定义实例:

            1. 1
            2. 2
            3. 3
            4. 4
            5. 5
                • 1
                • 2
                • 3
                • 4
                • 5
                new namespace.Person({
              • name:20
              • })

              2.2类和模块结合使用

              学过后台语言的人大多都习惯:一个类一个文件这样的话有利于我们关于我们的js代码,那么在dojo中如何实现呢?代码如下:

              • person.js
              1. 1
              2. 2
              3. 3
              4. 4
              5. 5
              6. 6
              7. 7
              8. 8
              9. 9
              10. 10
              11. 11
              12. 12
              13. 13
                  • 1
                  • 2
                  • 3
                  • 4
                  • 5
                  • 6
                  • 7
                  • 8
                  • 9
                  • 10
                  • 11
                  • 12
                  • 13
                  define(["dojo/_base/declare"],(declare){
                • return declare((){
                • return this.name+":"+this.age
                • }
                • })
                • })
                1. 1
                2. 2
                3. 3
                4. 4
                5. 5
                6. 6
                7. 7
                    • 1
                    • 2
                    • 3
                    • 4
                    • 5
                    • 6
                    • 7
                    require(["js/person"],102); Box-sizing: border-Box;">(Person) {
                  • new Person({
                  • name:20
                  • });
                  • alert(p.toString())
                  • });

                  假设我们的类名是namespace.Person,我们还可以这样引用(注意和上面的区别),也就是全局引用:

                  1. 1
                  2. 2
                  3. 3
                  4. 4
                  5. 5
                  6. 6
                  7. 7
                  8. 8
                  9. () {
                  10. new namespace.Person({
                  11. name:20
                  12. });
                  13. alert(p.toString())
                  14. });
                  • 运行结果

                  2.3关于类的继承

                  关于类的继承如何使用,在此处不多说,如果想要了解更多类的高级使用请查看官网:
                  dojo创建类

                  3.需求

                  在上面只是简单的介绍了一下如果创建类,如何使用类,那么现在我们从需求的方面说一下类的使用。

                  3.1需求一

                  假如我们新来了一个项目,然后项目经理说:小王,现在我想实现一个功能,提供一个点的坐标,然后给地图添加一个图标。你只需要给我一个接口就好了,具体怎么实现我不管。那么我们现在如何实现呢?
                  思路:创建一个模块,然后模块里面有一个类,类有一个方法方法可以给地图添加点图形就好了嘛。对的,但是有的同学会说,那么地图对象怎么来呢?答案是:我们可以通过构造函数传进来吗。

                  1. 1
                  2. 2
                  3. 3
                  4. 4
                  5. 5
                  6. 6
                  7. 7
                  8. 8
                  9. 9
                  10. 10
                  11. 11
                  12. 12
                  13. 13
                  14. 14
                  15. 15
                  16. 16
                  17. 17
                  18. 18
                  19. 19
                  20. 20
                  21. 21
                  22. 22
                  23. 23
                      • 1
                      • 2
                      • 3
                      • 4
                      • 5
                      • 6
                      • 7
                      • 8
                      • 9
                      • 10
                      • 11
                      • 12
                      • 13
                      • 14
                      • 15
                      • 16
                      • 17
                      • 18
                      • 19
                      • 20
                      • 21
                      • 22
                      • 23
                      define(["esri/graphic","esri/symbols/SimpleMarkerSymbol",0); Box-sizing: border-Box;">"esri/symbols/SimpleLineSymbol",0); Box-sizing: border-Box;">"dojo/colors",0); Box-sizing: border-Box;">"esri/layers/GraphicsLayer",136); Box-sizing: border-Box;">function (Graphic,SimpleMarkerSymbol,SimpleLineSymbol,Color,GraphicsLayer,declare){
                    • return declare(//定义map对象,由外界传入
                    • constructor: //提供方法用于添加
                    • addPoint:(point){
                    • var lineSymbol=new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,new Color([255,0,102); Box-sizing: border-Box;">0]),102); Box-sizing: border-Box;">2)
                    • var pSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CROSS,102); Box-sizing: border-Box;">100,lineSymbol,102); Box-sizing: border-Box;">0.25]));
                    • var g=new Graphic(point,pSymbol);
                    • var layer=new GraphicsLayer();
                    • layer.add(g)
                    • this.map.addLayer(layer);
                    •  
                    • }
                    • })
                    • })
                    1. 1
                    2. 2
                    3. 3
                    4. 4
                    5. 5
                    6. 6
                    7. 7
                    8. 8
                    9. 9
                    10. 10
                    11. 11
                    12. 12
                    13. 13
                    14. 14
                    15. 15
                    16. 16
                    17. 17
                    18. 18
                    19. 19
                        • 1
                        • 2
                        • 3
                        • 4
                        • 5
                        • 6
                        • 7
                        • 8
                        • 9
                        • 10
                        • 11
                        • 12
                        • 13
                        • 14
                        • 15
                        • 16
                        • 17
                        • 18
                        • 19
                        "esri/map",0); Box-sizing: border-Box;">"esri/layers/ArcGISDynamicMapServiceLayer",0); Box-sizing: border-Box;">"esri/geometry/Point",0); Box-sizing: border-Box;">"js/MyUtil",0); Box-sizing: border-Box;">"dojo/domReady!"],102); Box-sizing: border-Box;">(Map,ArcGISDynamicMapServiceLayer,Point,MyUtil) {
                      • var map=new Map("mapDiv")
                      • new Point(
                      • {
                      • x:"-107.13700471124938",y:"41.54667348528646",spatialReference:{
                      • wkid:"4326"
                      • }
                      • })
                      • new ArcGISDynamicMapServiceLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer");
                      • map.addLayer(layer);
                      • var util=new MyUtil({
                      • map:map
                      • });
                      • util.addPoint(p);
                      •  
                      • });

                      3.2需求二(很重要)

                      我们实现了需求一,但是突然有一天项目经理把你找来说:小王啊,我们的需求变了啊,上次的功能可能要改一改,我不提供点了,我想进行交互绘制图形。但是呢,我绘制的图形不添加到地图中,我想将它返回给我

                      3.2.1代码实现

                      这时候大家会想,这还不简单呢。我们直接直接绘制完图像,然后获得绘制的几何形状,直接return不就好了吗。我们的思路是这样的:
                      * 创建一个模块
                      * 模块中有一个getPoint方法,调取getPoint方法获得点的坐标

                      但是问题来了,我们先观察一下我们的代码

                      1. 1
                      2. 2
                      3. 3
                      4. 4
                      5. 5
                      6. 6
                      7. 7
                      8. 8
                      9. getPoint:() {
                      10. on(this.toobar,0); Box-sizing: border-Box;">"draw-complete",136); Box-sizing: border-Box;">this.showResult);
                      11. },showResult:(result){
                      12. var geometry=result.geometry;
                      13. }

                      观察代码我们发现问题了:我们调用了getPoint方法,但是呢,几何形状是在showResult方法中获得的,我们根本不能return,所以一开始我们的思路是错误的。

                      出现问题,那么我们就应该去解决问题,我们应该如何将我们的数据返回呢?答案是利用回调方法。我们在类中给外界提供一个接口,这个接口是一个函数,通过这个函数将我们的数据返回。所以我们是这样实现的

                      1. 1
                      2. 2
                      3. 3
                      4. 4
                      5. 5
                      6. 6
                      7. 7
                      8. 8
                      9. 9
                      10. 10
                      11. 11
                      12. 12
                      13. 13
                      14. 14
                      15. 15
                      16. 16
                      17. 17
                      18. 18
                      19. 19
                      20. 20
                      21. 21
                      22. 22
                      23. 23
                      24. 24
                      25. 25
                      26. 26
                      27. 27
                      28. 28
                          • 1
                          • 2
                          • 3
                          • 4
                          • 5
                          • 6
                          • 7
                          • 8
                          • 9
                          • 10
                          • 11
                          • 12
                          • 13
                          • 14
                          • 15
                          • 16
                          • 17
                          • 18
                          • 19
                          • 20
                          • 21
                          • 22
                          • 23
                          • 24
                          • 25
                          • 26
                          • 27
                          • 28
                          define(["dojo/on",0); Box-sizing: border-Box;">"dojo/_base/declare",0); Box-sizing: border-Box;">"esri/toolbars/draw"],102); Box-sizing: border-Box;">(on,declare,Draw){
                        • "mydraw",[],0); Box-sizing: border-Box;">//当前Map对象
                        • toobar://用于回调,传数据
                        • constructor:(args) {
                        • declare.safeMixin(this.toobar = new Draw(this.map,{ showTooltips: true });
                        • this.toobar.activate(Draw.POINT);
                        • },getPoint:(callback) {
                        • this.init();
                        • this.callback=callback;
                        • on(this.callback(result.geometry);
                        • }
                        • })
                        • });
                        1. 1
                        2. 2
                        3. 3
                        4. 4
                        5. 5
                        6. 6
                        7. 7
                        8. 8
                        9. 9
                        10. 10
                        11. 11
                        12. 12
                        13. 13
                        14. 14
                        15. 15
                        16. 16
                        17. 17
                            • 1
                            • 2
                            • 3
                            • 4
                            • 5
                            • 6
                            • 7
                            • 8
                            • 9
                            • 10
                            • 11
                            • 12
                            • 13
                            • 14
                            • 15
                            • 16
                            • 17
                            "dojo/dom",0); Box-sizing: border-Box;">"js/mydraw",dom,MyDraw) {
                          • "http://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer");
                          • map.addLayer(layer);
                          •  
                          • dom.byId("btn").onclick=(){
                          • var my=new MyDraw({
                          • map:map
                          • });
                          • my.getPoint((g) {
                          • alert(g)
                          • })
                          • }
                          •  
                          • });

                          3.2.2程序出错

                          问题又来了,我们的思路没问题了,但是一运行,程序报错了

                          仔细排错,发现this没有callback属性

                          这时候我们就纳闷了,到底哪里出错了呢,我们明明定义了callback啊,然后继续挑错发现了更有趣的事情

                          1. 1
                          2. 2
                          3. 3
                          4. 4
                          5. 5
                          6. 6
                          7. 7
                          8. 8
                          9. 9
                          10. 10
                          11. 11
                              • 1
                              • 2
                              • 3
                              • 4
                              • 5
                              • 6
                              • 7
                              • 8
                              • 9
                              • 10
                              • 11
                              getPoint:this.callback=callback;
                            • //此处的this是我们的mydraw类
                            • on((result){
                            • //此处this的指向变了,大家可以debug看一下
                            • this.callback(result.geometry);
                            • }

                            不知道大家还记不记得,在js中this关键字十分灵活,我们知道在类中this的使用是不可避免的,使用频率会非常高,我们还说过,在函数调用是,我们是可以控制this的指向的,在dojo中提供了一个模块叫做dojo/_base/lang,使用该模块我们可以控制this的指向,那么我们应该怎么用呢??修改错误,只需要修改一个地方便可

                            1. 1
                            2. 2
                            3. 3
                            4. 4
                            5. 5
                            6. 6
                            7. 7
                            8. getPoint:this.showResult));
                            9. },

                            注意:我使用on绑定事件的时候:控制了this的指向,在getPoint函数中this是我们的mydraw类,所以让调用showResult函数时,控制this为mydraw即可。

                            3.2.3程序运行

                            在次运行程序,终于成功了:

                            3.3 需求三

                            需求三就很简单了,有的同学在使用dojo的时候可能还会使用jQuery中类库(其实没必要,dojo已经很强大了),那么我们应该怎么办呢?如何在我们自己的模块中使用jquery呢?代码如下

                            1. 1
                            2. 2
                            3. 3
                            4. 4
                            5. 5
                            6. 6
                            7. 7
                            8. 8
                            9. define([declare(null,{
                            10. $:(args){
                            11. declare.safeMixin(this,args);
                            12. }
                            13. })
                            14. })

                            在使用我们类的时候(假设我们的Person):

                            1. 1
                            2. 2
                            3. 3
                                • 1
                                • 2
                                • 3
                                new Person({
                              • $:$
                              • });

                              原理就是将我们全局的$传给我们自定义模块。

                              4.再次介绍require加载模块

                              首先我们看一下我们加载的顺序:

                              • 第一:如果我们有自定义模块,那么通过dojoConfig配置我们自定义模块的路径
                              • 第二:加载init的js文件(注意一定要在dojoConfig加载)
                              • 第三:require是按照顺序加载的,比如我require首先加载的是dijit/registry,那么后面的function里面就写一个变量代表dijit/registry模块,此时变量的名称无所谓,仅仅代表该模块,但是注意:图中的①处代表的是一个js文件,图中的②是一个自定义的变量(用来代表该模块)。
                              • 第四:大家注意到,我require中的第一个参数有六个模块,但是function中,却只有四个变量。此处说明:如果我们在funtcion函数中用不到该模块(注意是在function中用不到,并不是说明其他地方用不到),那么我们尽量将该模块往后放。
                              • 第五:在此声明:图中的①处代表的是一个js文件,图中的②是一个自定义的变量,既然是一个自定义变量,那么就意味着我们可以随便写(用来代表前面的js文件)。可能有人问,一个文件夹下面有很多的类,我们随便写不就乱套了吗?这种情况是不存在的。在此声明:图中的①处代表的是一个js路径,同一个文件夹下面是不可能存在同名文件的。

                              4.总结

                              在此篇博客中,主要说了

                              • 如何创建类,如何使用类,其中我们可以用define方法让我们的类是一个文件,便于管理。
                              • 在类中如何利用回调函数返回数据
                              • 如何在类中使用类外变量(可以通过构造函数传进来)
                              • 在类中正确的使用dojo/_base/lang模块,控制我们的this关键字
                              • 重新介绍了require的加载过程
                              • 注意我们定义了很多的类和模块,但是我们程序的入口确只有一个

                              4.1本博客代码的下载地址:dojo_class

                              猜你在找的Dojo相关文章