dojo byid 子节点
一棵树 ,用于在父子关系中导航层次结构数据,可以帮助您轻松地理解一长串数据及其之间的关系。 Dojo提供了对创建树的支持,Dojo中的树遵循模型-视图-控制器(MVC)设计模式。 在数字树中,角色由以下组件扮演:
-
控制器(dojox.data存储)
- 负责以非关系数据库形式存储所有数据的存储。 模型(dijit.tree ForestStoreModel / TreeStoreModel)
- 根据用户选择的模型类型,以层次结构顺序格式化数据存储区的数据。 视图(dijit.Tree)
- 提供模型对象创建的数据视图的树。
在Dojo树中使用MVC时,树的创建从控制器开始,进入模型,然后进入视图,如图1所示。
图1.遵循MVC设计模式的Dojo树
您可以使用各种Dojo数据存储在Dojo中创建树。 在本文中,学习使用基于REST API的Dojo商店JsonRestStore
创建延迟加载的Dojo树。
延迟加载
延迟加载是一种仅在需要时才从用户数据库中获取数据的技术。 仅从用户获取那些由用户扩展的节点,这可以提高树的性能。 延迟加载树可能导致便宜或昂贵的操作,具体取决于树将容纳的数据量。
对少量数据进行延迟加载会导致对服务器的多个请求,响应速度慢可能会导致用户感到沮丧。 但是,在具有大数据集的生产环境中,延迟加载始终提供优势。
在深入研究Dojo树的创建过程之前,下一节将介绍一些用于创建惰性加载树的基本概念。
道场树生成
道场树有几个重要的构建基块:
-
JsonRestStore
引用功能 -
deferItemLoadingUntilExpand
- JSON数据
JsonRestStore引用功能
JSON引用是JsonRestStore
提供的属性,通过该属性,您可以从另一个对象(而不包括实际对象)中获取对对象的引用。 JsonRestStore
的$ref
属性提供了从另一个对象引用另一个对象。
父子关系在运行时使用父节点中$ref
属性的值(即子节点的id
值)进行解析。 父节点的JSON对象可能类似于以下示例。
{
"id": "node1",
"name": "Subjects",
$ref: "child1"
}
子JSON对象将类似于以下示例。
{
"id": "child1",
"name": "Math",
$ref: "author1"
}
在第一个代码示例中,父节点的$ref
属性值为"child1"
,这意味着它引用了子节点的id
值。 父节点展开后,此值将在运行时解析(如本文稍后所示)。
在第二个代码示例中, id
"child1"
应该与父项的$ref
值完全匹配。 您可以继续进行此层次结构,类似于第二个示例中的$ref:"author1"
。
deferItemLoadingUntilExpand属性
Dojo Toolkit 1.4为Dojo树模型引入了一个新属性deferItemLoadingUntilExpand
。 早期版本的Dojo Toolkit缺少此属性,因此,在扩展任何子节点时,将提取所有树节点并将其加载到Dojo数据存储中。 但是,如果使用deferItemLoadingUntilExpand
属性,则将deferItemLoadingUntilExpand
设置为true
,它将仅获取请求节点的子节点,并在数据存储区中进行更新。 这有助于提高延迟加载树的效率。
Dojo树的JSON数据
JsonRestStore
具有JSON格式的数据的预定义架构。 在开始生成树之前,强烈建议您对JSON有基本的了解。 本文对树使用JSONObject
, JSONArray
和JsonString
,因此该示例以正确的格式获取数据。 本文的示例将从Java™类获取JSON数据,并且需要JSON数据作为返回字符串,由JsonRestStore
处理。
创建一个延迟加载的Dojo树
在本节中,您将使用JsonRestStore
创建一个延迟加载的Dojo树。 该示例为虚拟的书店创建了一棵树。 该树将包含有关书籍和作者的信息,并且书籍和作者之间存在层次结构。 您将使用带有延迟加载的Dojo树来创建此层次结构,以使应用程序更高效。
Dojo树遵循MVC模型,并且该模型具有两种形式: TreeStoreModel
和ForestStoreModel
。 该示例使用ForestStoreModel
构造树。 不过,首先,您需要为应用程序声明和定义JsonRestStore
。 您可以通过使用REST服务或直接将URL映射到目标参数来创建JsonRestStore
。
该示例声明一个服务,该服务将基于Dojo的异步JavaScript和XML(Ajax)调用放置到Java类中,该Java类负责从数据库获取数据并以JSON格式返回字符串。 从Java类检索后,数据将更新为service参数。
首先使用JsonRestStoreTree.jsp代码生成客户端代码,如清单1所示。
清单1.创建REST服务和JsonRestStore
var booksService = function(query, queryOptions)
{
return dojo.xhrGet({url:"
/BookStoreTree/com/tree/actions/JsonRestStoreTreeAction.action",
handleAs:'json',content:{query:query, queryOptions:queryOptions}});
};
var booksDataStore = new
dojox.data.JsonRestStore({target:'booksData',service: booksService,
labelAttribute:"name"});
或者,您可以通过指定商店的目标直接创建商店,如清单2所示。
清单2.使用目标参数创建Store
var booksDataStore = new dojox.data.JsonRestStore({target:
"/BookStoreTree/com/tree/actions/JsonRestStoreTreeAction.action ",
labelAttribute:"name"});
现在已经创建了商店,您需要使用ForestStoreModel
创建模型。 该示例以编程方式创建模型,如清单3所示。该代码将deferItemLoadingUntilExpand
的值deferItemLoadingUntilExpand
为true
。
清单3.创建树模型
var treeModel = new dijit.tree.ForestStoreModel({
store: booksDataStore,
deferItemLoadingUntilExpand: true,
rootLabel: "Subjects",
childrenAttrs: ["children"]
});
商店和模型已经准备就绪,所以继续创建Dojo树,如清单4所示。
清单4.创建Dojo树
<div dojoType="dijit.Tree" model="treeModel" persist="false" id="booksDataTree">
与处理用于生成树的客户端代码一样,开始编写Java代码以获取JSON格式的书籍的初始数据。
清单5中的代码返回数据的JSON格式。 随后将数据存储到booksDataStore
。
清单5. Java代码获取初始树的数据
public String getSubjectList() throws IOException
{
//Code to query subjects list from DB
//call DB-side function to get the books object
Map<String,String> booksNameMap = new
HashMap<String, String>();
//ex. Map booksNameMap =
server.GetListOfSubjects();
//above code is specific to application
JSONObject subObj = new JSONObject();
JSONArray subArray = new JSONArray();
for(int i=0; i< booksNameMap.size(); i ++)
{
String subjectName = booksNameMap.get(i);
subObj.put("id", subjectName +"Id");
subObj.put("name", subjectName);
subObj.put("$ref","author"+ i);
subObj.put("children", true);
}
subArray.add(subObj);
jsonString = subArray.serialize(true);
setJsonString(jsonString);
return jsonString;
}
清单5中的代码将数据存储在JSONArray
,这对于加载树的初始数据是必需的。 创建的树如图2所示。
图2.初始Dojo树
现在已经创建了树,您可以展开一个节点,该节点为请求的节点获取数据。 您将看到扩展任何节点时引用属性如何发挥重要作用。
在清单6中,当扩展id
"subjectNameId"
的父节点时,将调用getListOfAuthors()
方法。 因为$ref
"subjectNameId "
的$ref
属性设置为"author1"
,所以"author1"
的节点数据被返回并作为树的子节点自动更新。
清单6.获取子节点的数据
public String getListOfAuthors() throws IOException
{
//Code to query authors list from DB
//call DB-side function to instantiate
authorsNameMap object
Map<String,String> authorsNameMap = new
HashMap<String, String>();
//ex. Map authorsNameMap =
server.GetListOfAuthors();
//above code is specific to application
JSONObject authObj = new JSONObject();
for(int i=0; i< authorsNameMap.size(); i ++)
{
authObj.put("id", "author"+i);
authObj.put("name",
authorsNameMap.get(i));
}
jsonString = authObj.serialize(true);
setJsonString(jsonString);
return jsonString;
}
与JSONArray
格式的父数据JSONArray
,该示例以JSONObject
格式发送子节点的数据。 这是必不可少的,因为子数据以JSONObject
格式捕获。
创建的树如图3所示。展开C编程节点后,一个请求将发送到服务器,并且仅在此节点获取数据。
图3.延迟加载的Dojo树
从树中删除节点
删除,添加或更新节点时,不会更新树视图。 相反,您需要更新连接到数据存储的树模型。 本质上,如果要修改树,则需要更新数据存储。
在书店示例中,商店数据具有有关各种书的信息,每个书均由书的"id"
值唯一标识。 您将使用"id"
值获取节点,并将其从存储中删除。 清单7显示了处理从树中删除节点的代码段。
清单7.从Dojo树中删除一个节点
function deleteNodeFromTree()
{
//delete from the bookstore//
booksDataStore.fetchItemByIdentity({
identity: 'AlgorithmsId',
onItem: dojo.hitch(booksDataStore,
function(item) {
booksDataStore.deleteItem(item);
booksDataStore.save({
onComplete: function() {
alert("Save Complete");
}
});
})
});
}
清单7中的代码通过节点的标识(在这种情况下为'AlgorithmsId'
)从存储中获取节点。 获取所需的节点后,将deleteItem()
JsonRestStore
的deleteItem()
方法,该方法将从数据存储中删除'AlgorithmsId'
数据。 删除节点后,Dojo树如图4所示。
图4.算法节点被删除
将节点添加到树中
JsonRestStore
具有newItem(item, {parent : parentItem, attribute : children})
函数,用于向商店添加新项目,您可以使用它向树中添加新节点。 该方法的调用类似于示例中用于删除节点的deleteItem()
方法。 在书店中,将"AKDas"
添加为"AKDas"
数据结构”节点的子级。
清单8.将节点添加到Dojo树
function addNodeToTree()
{
//add data to the bookstore//
booksDataStore.fetchItemByIdentity({
identity: 'AlgorithmsId',
onItem: dojo.hitch(booksDataStore,
function(item) {
booksDataStore.newItem(
name: 'A.K.Das',
ref: $'AlgorithmsId',
item);
booksDataStore.save({
onComplete: function() {
alert("Add node
Complete");
}
});
})
});
}
清单8中的代码获取要在其中添加新子项的项目。 或者,换句话说,新节点将成为您从商店中获取的节点的子节点。 父节点是'AlgorithmsId'
,它是Subject,本示例将'AKDas'
添加为作者。 图5显示了添加新节点后的树。
图5.将子节点添加到Algorithms节点
更新树的节点
要更新树的节点,您需要更新数据存储中现有的数据。 同样,该示例调用数据存储区的fetchItemByIdentity
方法,并使用JsonRestStore
的setValue(item, attribute, value)
方法更新目标节点的数据。
清单9显示了代码,其中在booksDataStore
上调用了setValue(item, attribute, value)
方法,并且为所选节点更改了'name'
属性的值。
清单9. Dojo树的更新节点
function updateNodeToTree()
{
//update data of the bookstore//
booksDataStore.fetchItemByIdentity({
identity: 'AlgorithmsId',
onItem: dojo.hitch(booksDataStore,
function(item) {
booksDataStore.setValue(item, 'name',
'Discrete');
booksDataStore.save({
onComplete: function() {
alert("Update Complete");
}
});
})
JsonDataStore
的setValue(item, attribute, value)
方法更新现有的节点属性。 清单9中的代码将'AlgorithmsId'
节点的名称从Algorithms更新为Discrete。 图6显示了更新后的树。
图6.更新为离散的节点算法
结论
基于Dojo和基于REST的JsonRestStore
共同为延迟加载树提供了出色的支持,这些树允许高效地获取和显示大型数据集。 使用JsonRestStore
提供的方法时,更新,添加和删除Dojo树很容易。 Dojo和JsonRestStore
使您可以利用Dojo树上的延迟加载功能。 通过将Dojo Tree小部件与基于REST的数据存储完美结合,可以创建高级的,基于富文本的UI。
翻译自: https://www.ibm.com/developerworks/web/library/wa-lazyload/index.html
dojo byid 子节点