I believe I've found a bug in Dojo 1.1.1, where objects instantiated using the parser cannot be successfully subclassed. My demo code subclasses dojo.dnd.Moveable so that the objects start in random positions on the screen. I include two versions: one that works (using addOnLoad()), and one that doesn't (using the parser).
This code works: the objects are built programmatically by addOnLoad(). (The parseOnLoad:true and dojoType statements are ignored.)
<html>
<head>
<title>Subclassing Moveables</title>
<style type="text/css">
.moveable {
background: #FFFFBF;
border: 1px solid black;
width: 100px;
height: 100px;
cursor: pointer;
position: absolute;
}
</style>
<!-- load the dojo toolkit base -->
<script type="text/javascript" src="js/dojo-release-1.1.1/dojo/dojo.js"
djConfig="parseOnLoad:true, usePlainJson:true"></script>
<script type="text/javascript">
dojo.require("dojo.dnd.Moveable");
dojo.declare("MyMoveable", dojo.dnd.Moveable, {
constructor:
function(node, params) {
dojo.mixin(this, params);
node.style.left = Math.random() * 400 + 'px';
node.style.top = Math.random() * 400 + 'px';
}
}
);
dojo.addOnLoad(function() {
var nodes = dojo.query(".moveable");
for (var x = 0; x < nodes.length; x++) {
var node = nodes[x];
var moveable = new MyMoveable(node);
}
});
</script>
</head>
<body>
<div class="moveable" dojoType="MyMoveable" ></div>
<div class="moveable" dojoType="MyMoveable" ></div>
<div class="moveable" dojoType="MyMoveable" ></div>
</body>
</html>When loaded, this page creates three Movable objects that start in random locations.
Now, here's a version with the addOnLoad() replaced by dojo.require("dojo.parser"):
<html>
<head>
<title>Subclassing Moveables</title>
<style type="text/css">
.moveable {
background: #FFFFBF;
border: 1px solid black;
width: 100px;
height: 100px;
cursor: pointer;
position: absolute;
}
</style>
<!-- load the dojo toolkit base -->
<script type="text/javascript" src="js/dojo-release-1.1.1/dojo/dojo.js"
djConfig="parseOnLoad:true, usePlainJson:true"></script>
<script type="text/javascript">
dojo.require("dojo.dnd.Moveable");
dojo.declare("MyMoveable", dojo.dnd.Moveable, {
constructor:
function(node, params) {
dojo.mixin(this, params);
node.style.left = Math.random() * 400 + 'px';
node.style.top = Math.random() * 400 + 'px';
}
}
);
dojo.require("dojo.parser");
</script>
</head>
<body>
<div class="moveable" dojoType="MyMoveable" ></div>
<div class="moveable" dojoType="MyMoveable" ></div>
<div class="moveable" dojoType="MyMoveable" ></div>
</body>
</html>In THIS version, the three Moveables are created, but their initial positions are the default (0, 0). For some reason, the MyMoveable constructor isn't being called. (In this situation, I haven't been able to get ANY subclass functions to be called.)
Am I missing something?
Thanks,
Dan

From the book page about
From the book page about Understanding the Parser: http://dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-...
"If the class declares a method with the name markupFactory, that function will be used to create the object instance, instead of the constructor."
So, you need to add this to your declaration:
return new MyMoveable(node, params);
}
Works, but is this a design flaw?
Your suggestion worked, but perhaps this points out an API design flaw. Here's how I believe it currently works:
MyMoveable.markupFactorynew Moveable()and returns itI believe that markupFactory methods should create a new instance of the specified type, not a new instance of the current type. If the actual markup specifies a subclass, then the markupFactory should create a new instance of that subclass. I don't know enough about Dojo's object tools to know how this is done; perhaps this would require a different set of arguments to markupFactory (e.g.
node, type, params).P.S. The switching of the parameter order between markupFactory [params, node] and the constructor [node, params] is nasty; is it too late to make them consistent (i.e. would likely break all existing code)? Could both of these be fixed at the same time?
P.P.S. I don't know how to do it, but should this thread be moved to the Dojo Core Development Discussion forum?
Yes, it is inconvenient, but
Yes, it is inconvenient, but we should live with that until 2.0 hits. The reason is simple — you actually mentioned it in your "P.S.". It happened because the DnD actually predates the parser. For now just remember to define a trivial adapter — that's what the markupFactory() is.
Could an updated API call the correct (subclass) constructor?
I hear you about waiting for 2.0. I was wondering, though; if a subclass' XXXXX method is invoked, and it turns out XXXXX is implemented by the superclass, when the superclass' XXXXX method invokes method YYYYY on the object can the subclass' YYYYY handle the invocation? In other words, is the Dojo object model able to implement what I think it should implement, even if it's not yet the time for it to do so?
(was that coherent?)
I am not sure it is possible
I am not sure it is possible without enforcing more conventions, which is a breaking change at this point.