Tree 由JsonRestStore和jsonp支持的延迟加载dojo树
我正在尝试使用Dojo工具包实现一个跨域、延迟加载树。到目前为止,我已经正确显示了顶级节点,但单击expando时,我得到了一个“延迟已解决”错误,我不知道为什么。通过查看firebug网络选项卡,我可以看到fetch方法似乎正在工作。我认为我的问题在我的_processResults方法中,可能与其中的_loadObject的定义有关 我觉得我应该更了解Dojo,因为我花了很多时间试图理解它。但是,唉,它真是一只野兽。。。我在其中一个sitepen博客()中看到一些关于JSONP和懒散加载不起作用的内容,但没有提到除了JSONP是asyncronus之外为什么不可能。如果Dojo只是将传入的json数据塞进存储中,我不明白这有什么关系 也许这与我对数据的格式化有关-sitepen()上的另一个例子是使用jsonreststore在展开节点之前不会加载项,而我的格式在展开节点之前不会加载项,但在展开节点之前不会加载子节点 不用多说,这里是ta codezTree 由JsonRestStore和jsonp支持的延迟加载dojo树,tree,dojo,lazy-loading,jsonp,deferred,Tree,Dojo,Lazy Loading,Jsonp,Deferred,我正在尝试使用Dojo工具包实现一个跨域、延迟加载树。到目前为止,我已经正确显示了顶级节点,但单击expando时,我得到了一个“延迟已解决”错误,我不知道为什么。通过查看firebug网络选项卡,我可以看到fetch方法似乎正在工作。我认为我的问题在我的_processResults方法中,可能与其中的_loadObject的定义有关 我觉得我应该更了解Dojo,因为我花了很多时间试图理解它。但是,唉,它真是一只野兽。。。我在其中一个sitepen博客()中看到一些关于JSONP和懒散加载不起
<script type="text/javascript">
dojoConfig = {
parseOnLoad: true,
isDebug: true,
usePlainJson: true
};
</script>
<script type="text/javascript" src="scripts/dojo_16/dojo/dojo.js"></script>
<script type="text/javascript">
dojo.require("dojo.parser");
dojo.require("dojo.io.script");
dojo.require("dojox.rpc.Service");
dojo.require("dojox.data.ServiceStore");
dojo.require("dijit.tree.ForestStoreModel");
dojo.require("dijit.Tree");
dojo.addOnLoad(function(){
var mySmd = {
"SMDVersion": "2.0",
"id": "http://urlbehindfirewall/testtree/",
"description": "This is the service to get to the finder app backend data",
transport: "JSONP",
envelope: "URL",
additionalParameters: true,
target: "http://urlbehindfirewall/testtree/",
services: {
"getChildrenNodes": {
"target": "getChildrenNodes.php",
parameters: [
{ name: "nodeId", type: "integer"}
]
}
}
};
var myService = new dojox.rpc.Service(mySmd);
var myStoreParams = {
service : myService.getChildrenNodes,
idAttribute : "Node_Id",
labelAttribute : "Display_Name",
_processResults: function(results, def){
var _thisStore = this;
for(i in results){
results[i]._loadObject = function(callback){
_thisStore.fetch({
query: { nodeId: this.Node_Id },
onItem: callback
});
delete this._loadObject;
};
}
return {totalCount: results.length, items: results};
}
};
var myStore = new dojox.data.ServiceStore(myStoreParams);
//create forestTreeModel
var treeModelParams = {
store: myStore,
deferItemLoadingUntilExpand: true,
childrenAttrs: ["Children_Nodes"],
rootId : 1,
query: 1
};
var treeModel = new dijit.tree.ForestStoreModel(treeModelParams);
var myTree = new dijit.Tree({
model: treeModel,
id: "myTree",
showRoot: false
});
dojo.byId("treeContainer").appendChild(myTree.domNode);
myTree.startup();
});
</script>
展开上述任何一个节点都将得到该节点的子节点,因此2将得到5,6,7,8的节点数组。(对于当前实现,可能不需要有子节点ID和子节点,但不应该破坏任何内容否?)
所以,我确信现在眼睛都睁大了,重申一下这个问题——是什么造成了这个“推迟已经解决”的错误?使用JSONP可以在树中进行延迟加载吗?不同的json结构会解决我的延迟加载问题吗?是否可以在dojo中重新格式化数据以使其正常工作?(我认为这就是_processResults方法…)是否有任何可公开访问的树数据服务可供实践
谢谢大家 经过大量的实验和挫折,我的发现如下: 是的,可以使用JSONP延迟加载树。是的,将数据转换成不同的格式有助于解决延迟加载问题。我在路上发现了一些绊脚石,我将在后面提到 下面是工作实现的代码。首先是服务: invokeService.php
$callback = $_GET["callback"];
$nodeName = $_GET["node"];
$fileName = "pretendServiceJson/".$nodeName.".js";
print($callback . "(" . file_get_contents($fileName) . ")" );
?>
json/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"
}
]
}
]
{
"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/3.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"
}
]
}
]
{
"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>
dojo.require(“dojo.parser”);
require(“dojo.io.script”);
require(“dojox.rpc.Service”);
require(“dojox.data.JsonRestStore”);
require(“dijit.tree.ForestStoreModel”);
dojo.require(“dijit.Tree”);
dojo.addOnLoad(函数(){
var mySmd={
“SMDVersion”:“2.0”,
“id”:”http://localhost/pretendService.php",
“说明”:“这是获取finder应用程序后端数据的服务”,
传输:“JSONP”,
信封:“URL”,
其他参数:true,
目标:“http://localhost/",
服务:{
“getNode”:{
“target”:“invokeService.php”,
参数:[
{名称:“节点”,类型:“字符串”}
]
}
}
};
var myService=newdojox.rpc.Service(mySmd);
var myStore=new dojox.data.JsonRestStore({
服务:myService.getNode,
idAttribute:“节点\u Id”,
labelAttribute:“显示名称”
});
//创建forestTreeModel
变量treeModelParams={
商店:myStore,
DeliveItemLoadingUntilexPand:true,
childrenAttrs:[“Children”],
//rootId:“0”,
查询:“0”
};
var treeModel=新的dijit.tree.ForestStoreModel(treeModelParams);
var myTree=新的dijit.Tree({
型号:treeModel,
id:“myTree”,
showRoot:错,
坚持:错
});
byId(“treeContainer”).appendChild(myTree.domNode);
myTree.startup();
});
这里最大的教训是,有两种不同的方法(尽我所能做到最好)将数据放入存储,然后再放入树中。第一个数据加载将来自一个fetch,它需要一个项目数组。随后的延迟加载项(假设您正确设置了服务并得到了响应)将经过loadItem,并且该方法将需要一个对象
如果您将初始加载数据作为一个对象输入,您将不会在页面上看到任何树,尽管在firebug中看到了响应。但是没有错误
如果将延迟加载的数据作为数组输入,则会得到一个“TypeError:args.item未定义”-似乎loadItem第二次被调用为2x,而不是结果对象,它是一个空对象
如果在创建存储时定义了rootId,它将不会显示树,并给您一个“无法在指定层次插入节点”错误
以上所有错误都是使用JsonRestStore发现的。文档中说JsonRestStore继承了read函数