Search code examples
javascriptinheritancedojojs-amd

Dojo AMD 1.7 proper inheritance syntax using declare


I am struggling with this one:

I have this simple module in a file Module1.js:

define(['dojo/_base/declare', 'esri/map'], function (declare, map) {
    return declare(null,
        {
            name: "Module 1 name",

            constructor: function() {
                this.name = "module 1";
                //this.age = age;
                //this.currentResidence = currentResidence;
            },


            doSomething: function() {
                alert("calling from Module1");
            }
        });
});

I am trying to define a Module2 that inherits from Module1 but cannot seem to find the correct syntax: This is what I currently have:

define(["dojo/_base/declare",
        "esri/map",
        "tut/Module1"],
    function (declare, map, Module1) {
        return declare(null, [Module1],     // or tut/Module1
        {
            name: "Module 2 name",

            constructor: function () {
                this.name = "module 2";
                //this.age = age;                 
            },


            doSomething: function () {
                this.inherited(arguments); // Call superclass method...
                alert("calling from Module 2");
            },

            doSomething1: function () {
                alert("calling do soething 1 from module 2");
            }
        });
});

Somewhere else in my code, I am doing this:

  require(["tut/Module1", "tut/Module2"], function (Module1, Module2) {        
        var m = new Module1();
        m.doSomething();

        var m2 = new Module2();
        m2.doSomething();    

    }); 

I have the following dojoConfig defined just before I load the ESRI script that loads dojo as follows:

     <script type="text/javascript">
   var dojoConfig = {
                async : true,                               
                packages: [{ name: "tut", location: liveString + '/scripts/xxxx/utilities'}]            
            };
 </script>
 <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=3.0compact"></script>

The call to Module1 works indicating to me that my packages definition is correct. However, the call to Module2 throws an exception that says Object [object object] has no method 'doSomething'. I have tried some many different permutations, going back and forth with the manual but cannot find the right syntax. Now I am just guessing so will need some help.

How do I inherit from Module1 using Dojo 1.7 syntax?


Solution

  • The call to this.inherited(arguments) will work (if declare doesnt throw 'not a valid mixin', and neither constructor method throws errors).

    Try

    module 1

    define(["dojo/_base/declare",
            "esri/map"],
        function (declare, map) {
            return declare("tut.Module1", [], {     // or tut>>.<<Module1
              constructor: function() { this.name='a'; console.log('a ctor'); }
              log: function() { console.log(this.name); }
            });
        }
    });
    

    module 2 derived from module 1

    define(["dojo/_base/declare",
            "esri/map",
            "tut/Module1"],
        function (declare, map, Module1) {
            return declare("tut.Module2", [Module1],
              constructor: function() { this.name='B'; console.log('B ctor'); }
              log: function() { this.inherited(arguments); console.log(this.name); }
            });
        }
    });
    

    Try iterating over the constructor._meta 'bases' in a module instance ('new Module().constructor._meta') and that should give an idea of how this.inherited works

    Calling

    require(["tut/Module2"], function (M2) {
       var m = new M2();
       console.log('created');
       m.log()
    });
    

    would output

    "B ctor"
    "A ctor"
    "created"
    "A"
    "B"