Building a Javascript Object Explorer using the dojo Tree dijit.
Chapter 15 of Dojo: The Definitive Guide give a nice description of the Tree dijit using a TreeStoreModel or ItemFileReadStore.
Regarding the TreeStoreModel, Matthew Russell notes that "anything that presents this interface is just a valid model as the TreeStoreModel".
His comment give the answer to how one would build an object explorer.
The interface methods identified for readonly viewing are:
- getRoot
- mayHaveChildren
- getChildren
- getIdentity
- getLabel
The interface was documented in the book but can also be found in the source code:
- getRoot: function(onItem, onError)
- mayHaveChildren: function(/*dojo.data.Item*/ item)
- getChildren: function(/*dojo.data.Item*/ parentItem, /*function(items)*/ onComplete, /*function*/ onError)
- getIdentity: function(/* item */ item)
- getLabel: function(/*dojo.data.Item*/ item)
Armed with this information is was just a matter of writing the code:
var model = (function (args) {
if (dojo.isString(args)) args = { root: args };
args.root = args.root || "window";
args.identifier = args.identifier || "id";
args.label = args.label || "name";
if (dojo.isString(args.root)) {
var root = { parent: null };
root[args.identifier] = args.root;
root[args.label] = args.root;
args.root = root;
}
if (!args.root.parent) {
var parentPath = args.root[args.identifier].split(".");
parentPath = parentPath.splice(0, parentPath.length - 1);
parentPath = parentPath.join(".") || "dojo.global";
args.root.parent = dojo.getObject(parentPath);
}
var result = {
args: args,
_getValue: function (item) {
if (!item) return undefined;
return dojo.getObject(item[args.identifier], false, args.root.parent);
},
getRoot: function (f1, f2) {
f1(args.root);
},
mayHaveChildren: function (item) {
var value = this._getValue(item);
return dojo.isObject(value);
},
getIdentity: function (item) {
return item[args.identifier];
},
getLabel: function (item) {
return item[args.label];
},
getChildren: function (parentItem, callback) {
var p = this._getValue(parentItem), children = [], itemName, child;
for (itemName in p) {
try {
child = { };
child[args.label] = itemName;
child[args.identifier] = parentItem[args.identifier] + '.' + itemName;
children.push(child);
} catch (ex) {
console.log(ex);
}
}
callback(children);
}
}
return result;
} ("window"));
The args.identifier and args.label are in the interest of generality and don't add much value. Likewise _getValue requires the root parent and fully qualified identifiers. The alternative is to capture the value in the getChildren. Eliminate these features and the code is cut in half.
Links:
Nightly Build Tree Tests
Dojo Dictionary
No comments:
Post a Comment