После долгих экспериментов и разочарований это мои выводы:
Да, отложенная загрузка дерева возможна с использованием JSONP. Да, перевод моих данных в другой формат помог в решении проблемы отложенной загрузки. По пути я нашел несколько камней преткновения, о которых я упомяну позже.
Вот код для работающей реализации. Первый сервис:
pretendService.php
$callback = $_GET["callback"];
$nodeName = $_GET["node"];
$fileName = "pretendServiceJson/".$nodeName.".js";
print($callback . "(" . file_get_contents($fileName) . ")" );
?>
pretendServiceJson / 0.js - это начальная заметка загрузки данных это массив!
[
{
"Node_Id":"0",
"Display_Name":"",
"Children":[
{
"Node_Id":"1",
"Display_Name":"node 1",
"Obi_Id":"02",
"Secondary_Names":"Blah blah secondary name node 1"
},
{
"Node_Id":"2",
"Display_Name":"node 2",
"Obi_Id":"o2",
"Secondary_Names":"Blah blah secondary name node 2"
},
{
"$ref":"3",
"Display_Name":"node 3",
"Obi_Id":"o3",
"Secondary_Names":"Blah blah secondary name node 3",
"Children":true
},
{
"Node_Id":"4",
"Display_Name":"node 4",
"Obi_Id":"o4",
"Secondary_Names":"Blah blah secondary name node 4"
},
{
"Node_Id":"5",
"Display_Name":"node 5",
"Obi_Id":"o5",
"Secondary_Names":"Blah blah secondary name node 5"
}
]
}
]
pretendServiceJson / 3.js - это будет первый ленивый загруженный элемент - примечание это объект !!!
{
"Node_Id": "3",
"Display_Name": "node 3",
"Obi_Id": "o3",
"Secondary_Names": "Blah blah secondary name node 3",
"Children": [
{
"$ref": "6",
"Display_Name": "node 6",
"Obi_Id": "o6",
"Secondary_Names": "Blah blah secondary name 06",
"Children":true
},
{
"Node_Id": "7",
"Display_Name": "node 7",
"Obi_Id": "o7",
"Secondary_Names": "Blah blah secondary name 07"
}
]
}
Есть еще один json-файл 6.js, но я думаю, вы поняли. Наконец-то магия ...
dojo.require("dojo.parser");
dojo.require("dojo.io.script");
dojo.require("dojox.rpc.Service");
dojo.require("dojox.data.JsonRestStore");
dojo.require("dijit.tree.ForestStoreModel");
dojo.require("dijit.Tree");
dojo.addOnLoad(function(){
var mySmd = {
"SMDVersion": "2.0",
"id": "http://localhost/pretendService.php",
"description": "This is the service to get to the finder app backend data",
transport: "JSONP",
envelope: "URL",
additionalParameters: true,
target: "http://localhost/",
services: {
"getNode": {
"target": "pretendService.php",
parameters: [
{ name: "node", type: "string"}
]
}
}
};
var myService = new dojox.rpc.Service(mySmd);
var myStore = new dojox.data.JsonRestStore({
service : myService.getNode,
idAttribute : "Node_Id",
labelAttribute : "Display_Name"
});
//create forestTreeModel
var treeModelParams = {
store: myStore,
deferItemLoadingUntilExpand: true,
childrenAttrs: ["Children"],
//rootId : "0",
query: "0"
};
var treeModel = new dijit.tree.ForestStoreModel(treeModelParams);
var myTree = new dijit.Tree({
model: treeModel,
id: "myTree",
showRoot: false,
persist: false
});
dojo.byId("treeContainer").appendChild(myTree.domNode);
myTree.startup();
});
</script>
</head>
<body class="tundra">
<div id="treeContainer"></div>
</body>
</html>
Самый большой урок здесь состоит в том, что есть два отдельных метода (насколько я могу судить лучше), которые помещают данные в хранилище, а затем в дерево. Первый набор данных будет получен из выборки, и он будет ожидать множество элементов. Следующие лениво загруженные элементы (при условии, что вы правильно настроили службу и получаете ответы) будут проходить через loadItem, и этот метод будет ожидать объект.
Если у вас есть данные начальной загрузки, поступающие как объект, вы не увидите дерева на своей странице, несмотря на то, что видите ответ в firebug. Никаких ошибок, хотя.
Если у вас есть лениво загруженные данные, поступающие в виде массива, вы получаете «TypeError: args.item не определен» - кажется, что loadItem вызывается 2x, и второй раз вместо вашего результирующего объекта это пустой объект. 1033 *
Если у вас есть rootId, определенный при создании хранилища, оно не будет отображать дерево и выдает ошибку «Невозможно вставить узел при указанной иерархии».
Все вышеперечисленные ошибки были обнаружены с помощью JsonRestStore. В документации говорится, что JsonRestStore наследует функциональность чтения ServiceStore, но если я переключаю два хранилища, я получаю ошибку «Узел не может быть вставлен в указанную иерархию».
Одно из моих самых больших разочарований в Dojo - просто отсутствие документации, указывающей, как фактические данные успешно анализируются в элементах для хранилищ данных. Много говорят о гибкости и модульности хранилищ данных, но как получить мои данные и заставить их работать, до сих пор остается загадкой, и это решение пришло мне в голову, когда я ухватился за соломинку. Я хотел бы написать на сайте статью о том, как данные когда-нибудь станут элементами хранилища данных ...? :)
Надеюсь, это поможет кому-то еще. Удачного кодирования.