I'm having a some problem making JSonRest store and dijit.Tree with ForestModel. I've tried some combination of JsonRestStore and json data format following many tips on the web, with no success.
At the end, taking example form here http://blog.respondify.se/2011/09/using-dijit-tree-with-the-new-dojo-object-store/
I've made up this simple page (I'm using dojotolkit 1.7.2)
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Tree Model Explorer</title>
<script type="text/javascript">
djConfig = {
parseOnLoad : true,
isDebug : true,
}
</script>
<script type="text/javascript" djConfig="parseOnLoad: true"
src="lib/dojo/dojo.js"></script>
<script type="text/javascript">
dojo.require("dojo.parser");
dojo.require("dijit.Tree");
dojo.require("dojo.store.JsonRest");
dojo.require("dojo.data.ObjectStore");
dojo.require("dijit.tree.ForestStoreModel");
dojo.addOnLoad(function() {
var objectStore = new dojo.store.JsonRest({
target : "test.json",
labelAttribute : "name",
idAttribute: "id"
});
var dataStore = new dojo.data.ObjectStore({
objectStore : objectStore
});
var treeModel = new dijit.tree.ForestStoreModel({
store : dataStore,
deferItemLoadingUntilExpand : true,
rootLabel : "Subjects",
query : {
"id" : "*"
},
childrenAttrs : [ "children" ]
});
var tree = new dijit.Tree({
model : treeModel
}, 'treeNode');
tree.startup();
});
</script>
</head>
<body>
<div id="treeNode"></div>
</body>
</html>
My rest service responds the following json
{
data: [
{
"id": "PippoId",
"name": "Pippo",
"children": []
},
{
"id": "PlutoId",
"name": "Pluto",
"children": []
},
{
"id": "PaperinoId",
"name": "Paperino",
"children": []
}
]}
I've tried also with the following response (actually my final intention n is to use lazy loading for the tree)
{ data: [
{
"id": "PippoId",
"name": "Pippo",
"$ref": "author0",
"children": true
},
{
"id": "PlutoId",
"name": "Pluto",
"$ref": "author1",
"children": true
},
{
"id": "PaperinoId",
"name": "Paperino",
"$ref": "author2",
"children": true
}
]}
Neither of the two works. I see no error message in firebug. I simply see the root "Subject" on the page. Thanks to anybody could help in some way.
From a quick glance;
your serverside returns the wrong data. Here's the quickstart jsonrest from dojo reference guide, follow the GET part.
There is a difference, since the manner of how your REST request looks (GET from browser), the serverside should 1) return an array of items or 2) return an item.
Try remove the data key as such:
So this will not bring lazy loading capeabilities just yet? This must be because the model has quite a complex setup in your sample of code, first the REST
store
then an OBJECTanother store
, then a ForestTreemodel
and last a Treeview
. It is fairly simple to implement what the model has to offer our store, and lets skip the double-store definition. Otherwise the objectstore.query will call reststore.query - which im not entirely certain will work.Missing logic in the
RestStore
The Tree requires five model methods to render data as a tree:
getIdentity(object)
- Already provided by the store, and doesn't usually need to be reimplemented.mayHaveChildren(object)
- Indicates whether or not an object may have children (prior to actually loading the children). In this example, we will treat the presence of a "children" property as the indication of having children.getChildren(parent, onComplete, onError)
- Called to retrieve the children. This may execute asynchronously and should call the onComplete callback when finished. In this example, we will do a get() to retrieve the full representation of the parent object to get the children. Once the parent is fully loaded, we return the "children" array from the parent.getRoot(onItem)
- Called to retrieve the root node. The onItem callback should be called with the root object. In this example, we get() the object with the id/URL of "root" for the root object.getLabel(object)
- Returns the label for the object (this is the text that is displayed next to the node in the tree). In this example, the label is just the "name" property of the object.How could this be done then? Lets make a couple of definitions:
1) server sets for
jsonrest.target
'base', the ID 'root' and 2) server returns 'children' key allways, true if there are anyCreating Tree with a customized RestStore as model
We us the variable reststore, defined above - and simply set this as the model of the tree construct parameters
Serverside lazyloading JSON data setup
Leaving out most of the data in our children arrays, the payload sent can be reduced and lazyloading can be taken advantage of. For every One item received (e.g. /data/parents/number1parent) a full representation of the item itself must be filled in. If he/she has children, we need to 1) name these for getting
labels
in theview
- we use 'name' key, see getLabel method, 2) supply a unique ID and 3) indicate whether they may have children or not.The root JSON
With this, we will show
ROOT
+ Pippo
* Pluto
+ Paperino
Any item JSON
Should we feel like clicking Pippo to see his child objects, lets regress; Tree requests target
treeNode.item.children
which by design in the RestStore translates to a request for the object.id==PippoId - and a URL will be compiled, using thethis.target/object.parent-relations/object.id
shcema. In this case, server will respond with a full representation of the ultimate URLdata/PippoID
via GET.Note, that the 'full representation object' - the top level - has extra entities to it, examplewise shoosize and surname. However the children are still a 'short-form representaion object'.
Serverside PHP Rest implementation
So, for the sake of argument, heres a representation of how one could implement the rest-capeabilities with PHP. We will go under the assumption, that papparazies is a table in sql-db and that a
getPaparazi($id)
along withgetPapasKids($id)
function is implemented to retrieve data columns.First off, we need to tell apache how to handle this by a .htaccess modification. If youre new at this, check some of these resources:
Put this in /.htaccess where '/' is your DocumentRoot - and modify RewriteBase as nescessary
From the PHP perspective in index.php (rewritten handler for all non-existing file requests) we could simply create following:
See a SitePen blog for compiled info on reststores and trees