Login Register

Declaring a Class

Classes in Dojo are declared with a declare statement with a class name, super-class information, and body. Within the body can be variables and methods.

dojo.declare("ClassName", null, {/*class body*/});

(Note: ClassName is the basic name, but to avoid naming conflicts, use module names like com.coolness.ClassName. See modules for details. For simplicity sake, we will start out with using just the simple name.)

Let's add some more content to our class by giving it a name and showing what the constructor can do. Following is a Person class with a constructor and a moveToNewState() function:

dojo.declare("Person", null, {
        constructor: function(name, age, currentResidence){
                this.name=name;
                this.age=age;
                this.currentResidence=currentResidence;
        },
        moveToNewState: function(newState){
                this.currentResidence=newState;
        }
});

Note the use of anonymous functions here. You are passing to dojo.declare an associative array of anonymous functions. "That's not an anonymous function," you might say, "their names are constructor and moveToNewState!" Strictly speaking, no they aren't. They are anonymous functions with the keys constructor and moveToNewState.

The function named "constructor" is special. It gets called when you create an object with the "new" operator of JavaScript.

//create an instance of a new person
var matt= new Person('Matt', 25, 'New Mexico');

In pure JavaScript, this is handled by a prototype function named after the class - for example, Person.prototype. Dojo wires in your constructor as a part of the prototype, but then adds extra goodies like calling the superclass constructor and initializing extra properties.

Our Matt object who is 25 currently lives in New Mexico, but let's say he moves a little further west to California. We can set his new currentResidence with the Person class method moveToNewState():

matt.moveToNewState('California');

Now the current value of matt.currentResidence shows that he now lives in California.

If you have used prototypes in Javascript, the above example corresponds roughly to:
function Person(name, age, currentResidence){
        this.name=name;
        this.age=age;
        this.currentResidence=currentResidence;
},
Person.prototype.moveToNewState= function(newState) {
        this.currentResidence=newState;
}
But the dojo version is more compact and has added value as we will see later.

Additional Constructor Called Markup Factory

Note: there's also another "constructor": markupFactory. When creating widget instances by parsing markup, markup factory is used instead of constructor. See Understanding the Parser for more information.

Its confusing

I find the statement you made above somewhat confusing.
I can still have a constructor right ?
I really might need one ?
I know from test that any inits done in the markupFactory wont hold (out of scope)!
The calling is
markupFactory then constructor

your statement infers its one or the other.....this is very confusing.
Then again other than some one liners that have been put around here nobody has really defined what the markupFactory does (or at least I cannot find the concrete example of why it matters. As you can probably tell Java is not my thing. Uhmm and there I was thinking we were doing javascript !!

Markup factory enables detailed creation of objects

First, I forgot something from my previous comment - so, let's fix it... When creating widget instances by parsing markup, if markup factory exists, it is used instead of constructor. The corresponding block of code from the parser:

var markupFactory = clazz["markupFactory"];
if(!markupFactory && clazz["prototype"]){
  markupFactory = clazz.prototype["markupFactory"];
}
// create the instance
var instance = markupFactory ? markupFactory(params, node, clazz) : new clazz(params, node);

Explained: If the class (or it's prototype) has function called "markupFactory", then it's used (at least expected) to return an instance of the class. The function markupFactory is executed in the same scope as the parser, because the object doesn't exist yet.

After giving it a second thought, I realized that the markupFactory isn't a constructor - it's indeed a factory. Basically, markupFactory is like a constructor - it creates objects. It just lets you define how: you can choose the class you want to instantiate, or you can prepare and reorder the parameters as the constructor expects them. A simple markupFactory passes the parameters to the standard constructor of current class:

markupFactory: function(params, domNode, constructorFunction){
  //params: object that contains the markup attribute values,
  //with type conversion already completed.
  //domNode: the DOM node (the div in the code below)
  //constructorFunction: The constructor function matching
  //the dojoType in markup. In this example, example.Class
  var instance = new constructorFunction(params, domNode);
  //Do special initialization intialization here
  return instance;
}

More complex markupFactory in DojoData-class chooses to instantiate a certain class and sets the parameters for its constructor:

markupFactory: function(args, node){
  return new dojox.grid.data.DojoData(null, null, args);
},

(See issue 5503 - in this particular case hard-coding the class name wouldn't be necessary, as it could use constructorFunction parameter.)

Wikipedia page on factory method pattern gives some more examples and Design Patterns gives you the exact definition.

elaborating on the markupFactory

Once again Maine thank you very much for a very detailed description. That certainly makes it alot clearer .